Home

Atmel Studio 7 설치 후 Atmega128 작동시키기

Click the link to read the original article: Here =================== AT128A-75B 라는 Atmega128 MCU을 사용한 제품을 구매해서 처음 구동시켜보려고 합니다. 아두이노만 사용하다가...
Read More

C++ 기초

Click the link to read the original article: TCPSchool.com ==== C++ 개요 C++ C++은 기존의 C언어에 여러 가지 기능을 추가하여...
Read More

Bash 입문자를 위한 핵심 요약 정리 (Shell Script)

Click the link to read the original article: Here ================ Bash 입문자를 위한 기본적인 문법과 알고 있으면 좋은 것들만 정리했다....
Read More

Windows Hyper-V 사용법

Click the link to read the original article: Here ===================================== 안녕하세요. 도정진입니다.   저전력 서버를 사용하면서 윈도우를 쓸 일이 많아져서...
Read More

Hyper V 전체 화면으로 확대 하기 

Click the link to read the original article: Here =================================== Hyper V 전체 화면으로 확대 하기  윈도우 10 하이퍼 v는...
Read More

하이퍼-V (Hyper-V) 개념

Click the link to read the original article: Here ==================================== 하이퍼-V 란 무엇 인가 페러럴즈를 들어 보셨나요? 내가 맥을 사용할때...
Read More

10분만에 JASON API 개발하기

Click the link to read the original article: Here ================================== 10분만에 JSON API 개발하기 AXBoot Framework를 사용해서 JSON API를 10분 만에...
Read More

API Types and Information

Click the link to read the original article: Here ================================== 네이트 개발자센터 : http://devsquare.nate.com/ 개발블로그 : http://club.cyworld.com/devsquare 네이버 앱 팩토리 : http://appfactory.naver.com/ 네이버...
Read More

“5G 스마트폰 상용화 앞당긴다” 삼성, 엑시노스 모뎀 5100 공개

Click the link to read the original article: Here ===================================== 삼성전자, 업계 최초 5G 표준 멀티모드 모뎀 개발 [키뉴스 백연식...
Read More

5G를 위한 새로운 DBMS, ‘NewSQL DBMS’가 온다

Click the link to read the original article: Here ======================================= 과거 클라이언트/서버 환경에서 DBMS 선택 기준의 최우선 순위는 '안정성'이었다. DBMS가...
Read More

VoLTE Tutorial – Voice Over LTE

Click the link to read the original article: Here ==================== VoLTE Tutorial- This Voice over LTE beginners guide will help...
Read More

LTE architecture

Click the link to read the original article: Here =================================== LTE architecture The infrastructure of an LTE cellular network comprises...
Read More

Use Redis for session storage (Magento 2)

Use Redis for session storage (Magento 2)

Magento 2
Prerequisite Before you continue, install Redis. You can use Redis for session storage in Magento versions 2.0.6 and later only. Configure...
Read More
Use Redis for the Magento page and default cache

Use Redis for the Magento page and default cache

Magento 2
Use Redis for the Magento page and default cache Prerequisite Before you continue, install Redis. Configure Magento to use Redis for...
Read More
Aws Ec2 인스턴스에 Redis 설치하기

Aws Ec2 인스턴스에 Redis 설치하기

Web Server
Click the link to read the original article: 읽으러 가기 =============== 저는 Read cache를 위해 별도 EC2 인스턴스를 띄우고 redis를...
Read More
Redis, 레디스를 사용한 데이터베이스 캐싱서버 운영하기

Redis, 레디스를 사용한 데이터베이스 캐싱서버 운영하기

Web Server
Click the link to read the original article: 읽으러 가기 =========== Redis 서버의 구축 및 운영 등 여러가지 방안에 대하여 생각한...
Read More
[Spring]스프링 프레임워크 설치하기-eclipse(1)

[Spring]스프링 프레임워크 설치하기-eclipse(1)

Web Server
[Spring]스프링 프레임워크 설치하기-eclipse(1) [Spring]스프링 프로젝트 만들기-eclipse(2)   Click the link to read the original article: ========================= 자바를 하는 사람이 결국...
Read More
Install Apache Tomcat 8.0 and connect Eclipse

Install Apache Tomcat 8.0 and connect Eclipse

Web Server
Install Apache Tomcat 8.0 and connect Eclipse Click the link to read the original article: ============================== 홈 » 프로그래밍+DB » Apache Tomcat 8.0 설치...
Read More
Windows에서 JDK와 Eclipse 설치, Java 프로젝트 만들기

Windows에서 JDK와 Eclipse 설치, Java 프로젝트 만들기

Web Server
Windows에서 JDK와 Eclipse 설치, Java 프로젝트 만들기 Click the link to read the article: ====== 윈도에서 자바 프로그래밍을 하기 위해...
Read More
A/B Testing?

A/B Testing?

Web Server
A/B Testing? Click the link to go to the original site. ===== A/B testing이란? A/B testing은 웹이나 앱에서 A버전과 B버전을...
Read More
How to detect and clean malware from your Linux server using Maldet

How to detect and clean malware from your Linux server using Maldet

Magento 2
How to detect and clean malware from your Linux server using Maldet Click the link to the article page: =============...
Read More
RESTful API란 ?

RESTful API란 ?

Web Server
RESTful API란 ? Click the link to see the article: 개발 공부를 시작하고 자주 접하고 그냥 지나친 개념 중에 하나이다....
Read More
REST API란 무엇인가 #1 – 개념

REST API란 무엇인가 #1 – 개념

Web Server
REST API란 무엇인가 #1 - 개념 Click the link to see the article:  조대협 님께서 블로그에 개제 해주신 내용을 보고...
Read More
AngularJS 란 무엇인가?

AngularJS 란 무엇인가?

angularJs
AngularJS 란 무엇인가? Click to the link to go to the site: =============== AngularJS 개념 AngularJS 는 SPA(Single Page Application)...
Read More
1 2 3 4 5 23
Use Redis for session storage (Magento 2)
Magento 2

Use Redis for session storage (Magento 2)

Prerequisite

Before you continue, install Redis.

You can use Redis for session storage in Magento versions 2.0.6 and later only.

Configure Magento to use Redis for session storage

Following is a sample configuration to add to <your Magento install dir>app/etc/env.php:

'session' =>
array (
  'save' => 'redis',
  'redis' =>
  array (
    'host' => '127.0.0.1',
    'port' => '6379',
    'password' => '',
    'timeout' => '2.5',
    'persistent_identifier' => '',
    'database' => '2',
    'compression_threshold' => '2048',
    'compression_library' => 'gzip',
    'log_level' => '1',
    'max_concurrency' => '6',
    'break_after_frontend' => '5',
    'break_after_adminhtml' => '30',
    'first_lifetime' => '600',
    'bot_first_lifetime' => '60',
    'bot_lifetime' => '7200',
    'disable_locking' => '0',
    'min_lifetime' => '60',
    'max_lifetime' => '2592000'
  )
),

where

Parameter Meaning Default value
host Fully qualified hostname, IP address, or absolute path if using UNIX sockets. 127.0.0.1
port Redis server listen port. 6379
password Specifies a password if your Redis server requires authentication. empty
timeout Connection timeout, in seconds. 2.5
persistent_identifier Unique string to enable persistent connections (for example, sess-db0).

Known issues with phpredis and php-fpm.

empty
database Unique Redis database number, which is recommended to protect against data loss.

Important: If you use Redis for more than one type of caching (for example, page cache and session cache), the database numbers must be different.

0
compression_threshold Set to 0 to disable compression (recommended when suhosin.session.encrypt = On).

Known issue with strings of more than 64KB.

2048
compression_library Options: gziplzflz4 or snappy. gzip
log_level Set to any of the following, listed in order from least verbose to most verbose:

  • 0 (emergency: only the most severe errors)
  • 1 (alert: immediate action required)
  • 2 (critical: application component unavailable)
  • 3 (error: runtime errors, not critical but must be monitored)
  • 4 (warning: additional information, recommended)
  • 5 (notice: normal but significant condition)
  • 6 (info: informational messages)
  • 7 (debug: the most information for development or testing only)
1
max_concurrency Maximum number of processes that can wait for a lock on one session. For large production clusters, set this to at least 10% of the number of PHP processes. 6
break_after_frontend Number of seconds to wait before trying to break the lock for frontend (that is, storefront) session. 5
break_after_adminhtml Number of seconds to wait before trying to break the lock for an adminhtml (that is, Magento Admin) session. 30
first_lifetime Lifetime, in seconds, of session for non-bots on the first write, or use 0 to disable. 600
bot_first_lifetime Lifetime, in seconds, of session for bots on the first write, or use 0 to disable. 60
bot_lifetime Lifetime, in seconds, of session for bots on subsequent writes, or use 0 to disable. 7200
disable_locking Disable session locking entirely. false
min_lifetime Minimum session lifetime, in seconds. 60
max_lifetime Maximum session lifetime, in seconds. 2592000 (720 hours)

Basic verification

To verify that Redis and Magento are working together, use the following commands:

Redis monitor command

In a command prompt on the server on which Redis is running, enter:

redis-cli monitor

Refresh your storefront page and you’ll see output similar to the following.

Session storage

If you use Redis for session storage, you’ll see output similar to the following:

1476824834.187250 [0 127.0.0.1:52353] "select" "0"
1476824834.187587 [0 127.0.0.1:52353] "hmget" "sess_sgmeh2k3t7obl2tsot3h2ss0p1" "data" "writes"
1476824834.187939 [0 127.0.0.1:52353] "expire" "sess_sgmeh2k3t7obl2tsot3h2ss0p1" "1200"
1476824834.257226 [0 127.0.0.1:52353] "select" "0"
1476824834.257239 [0 127.0.0.1:52353] "hmset" "sess_sgmeh2k3t7obl2tsot3h2ss0p1" "data" "_session_validator_data|a:4:{s:11:\"remote_addr\";s:12:\"10.235.34.14\";s:8:\"http_via\";s:0:\"\";s:20:\"http_x_forwarded_for\";s:0:\"\";s:15:\"http_user_agent\";s:115:\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\";}_session_hosts|a:1:{s:12:\"10.235.32.10\";b:1;}admin|a:0:{}default|a:2:{s:9:\"_form_key\";s:16:\"e331ugBN7vRjGMgk\";s:12:\"visitor_data\";a:3:{s:13:\"last_visit_at\";s:19:\"2016-10-18 21:06:37\";s:10:\"session_id\";s:26:\"sgmeh2k3t7obl2tsot3h2ss0p1\";s:10:\"visitor_id\";s:1:\"9\";}}adminhtml|a:0:{}customer_base|a:1:{s:20:\"customer_segment_ids\";a:1:{i:1;a:0:{}}}checkout|a:0:{}" "lock" "0"

... more ...

Page caching

If you use Redis for page caching, you’ll see output similar to the following:

1476826133.810090 [0 127.0.0.1:52366] "select" "1"
1476826133.816293 [0 127.0.0.1:52367] "select" "0"
1476826133.817461 [0 127.0.0.1:52367] "hget" "zc:k:ea6_GLOBAL__DICONFIG" "d"
1476826133.829666 [0 127.0.0.1:52367] "hget" "zc:k:ea6_DICONFIG049005964B465901F774DB9751971818" "d"
1476826133.837854 [0 127.0.0.1:52367] "hget" "zc:k:ea6_INTERCEPTION" "d"
1476826133.868374 [0 127.0.0.1:52368] "select" "1"
1476826133.869011 [0 127.0.0.1:52369] "select" "0"
1476826133.869601 [0 127.0.0.1:52369] "hget" "zc:k:ea6_DEFAULT_CONFIG_CACHE_DEFAULT__10__235__32__1080MAGENTO2" "d"
1476826133.872317 [0 127.0.0.1:52369] "hget" "zc:k:ea6_INITIAL_CONFIG" "d"
1476826133.879267 [0 127.0.0.1:52369] "hget" "zc:k:ea6_GLOBAL_PRIMARY_PLUGIN_LIST" "d"
1476826133.883312 [0 127.0.0.1:52369] "hget" "zc:k:ea6_GLOBAL__EVENT_CONFIG_CACHE" "d"
1476826133.898431 [0 127.0.0.1:52369] "hget" "zc:k:ea6_DB_PDO_MYSQL_DDL_STAGING_UPDATE_1" "d"
1476826133.898794 [0 127.0.0.1:52369] "hget" "zc:k:ea6_RESOLVED_STORES_D1BEFA03C79CA0B84ECC488DEA96BC68" "d"
1476826133.905738 [0 127.0.0.1:52369] "hget" "zc:k:ea6_DEFAULT_CONFIG_CACHE_STORE_DEFAULT_10__235__32__1080MAGENTO2" "d"

... more ...

1476826210.634998 [0 127.0.0.1:52439] "hmset" "zc:k:ea6_MVIEW_CONFIG" "d" "a:18:{s:19:\"design_config_dummy\";a:4:{s:7:\"view_id\";s:19:\"design_config_dummy\";s:12:\"action_class\";s:39:\"Magento\\Theme\\Model\\Indexer\\Mview\\Dummy\";s:5:\"group\";s:7:\"indexer\";s:13:\"subscriptions\";a:0:{}}s:14:\"customer_dummy\";a:4:{s:7:\"view_id\";s:14:\"customer_dummy\";s:12:\"action_class\";s:42:\"Magento\\Customer\\Model\\Indexer\\Mview\\Dummy\";s:5:\"group\";s:7:\"indexer\";s:13:\"subscriptions\";a:0:{}}s:13:\"cms_page_grid\";a:4:{s:7:\"view_id\";s:13:\"cms_page_grid\";s:12:\"action_class\";s:43:\"Magento\\Catalog\\Model\\Indexer\\Category\\Flat\";s:5:\"group\";s:7:\"indexer\";s:13:\"subscriptions\";a:1:{s:8:\"cms_page\";a:3:{s:4:\"name\";s:8:\"cms_page\";s:6:\"column\";s:7:\"page_id\";s:18:\"subscription_model\";N;}}}s:21:\"catalog_category_flat\";a:4:{s:7:\"view_id\";s:21:\"catalog_category_flat\";s:12:\"action_class\";s:43:\"Magento\\Catalog\\Model\\Indexer\\Category\\Flat\";s:5:\"group\";s:7:\"indexer\";s:13:\"subscriptions\";a:6:{s:23:\"catalog_category_entity\";a:3:{s:4:\"name\";s:23:\"catalog_category_entity\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";N;}s:31:\"catalog_category_entity_decimal\";a:3:{s:4:\"name\";s:31:\"catalog_category_entity_decimal\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";s:71:\"Magento\\CatalogStaging\\Model\\Mview\\View\\Category\\Attribute\\Subscription\";}s:27:\"catalog_category_entity_int\";a:3:{s:4:\"name\";s:27:\"catalog_category_entity_int\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";s:71:\"Magento\\CatalogStaging\\Model\\Mview\\View\\Category\\Attribute\\Subscription\";}s:28:\"catalog_category_entity_text\";a:3:{s:4:\"name\";s:28:\"catalog_category_entity_text\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";s:71:\"Magento\\CatalogStaging\\Model\\Mview\\View\\Category\\Attribute\\Subscription\";}s:31:\"catalog_category_entity_varchar\";a:3:{s:4:\"name\";s:31:\"catalog_category_entity_varchar\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";s:71:\"Magento\\CatalogStaging\\Model\\Mview\\View\\Category\\Attribute\\Subscription\";}s:32:\"catalog_category_entity_datetime\";a:3:{s:4:\"name\";s:32:\"catalog_category_entity_datetime\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";s:71:\"Magento\\CatalogStaging\\Model\\Mview\\View\\Category\\Attribute\\Subscription\";}}}s:24:\"catalog_category_product\";a:4:{s:7:\"view_id\";s:24:\"catalog_category_product\";s:12:\"action_class\";s:46:\"Magento\\Catalog\\Model\\Indexer\\Category\\Product\";s:5:\"group\";s:7:\"indexer\";s:13:\"subscriptions\";a:2:{s:23:\"catalog_category_entity\";a:3:{s:4:\"name\";s:23:\"catalog_category_entity\";s:6:\"column\"

... more ...

Redis ping command

Enter the following command:

redis-cli ping

PONG should be the response.

If both commands succeeded, Redis is set up properly.

More information

redis-cli command reference

Use Redis for the Magento page and default cache
Magento 2

Use Redis for the Magento page and default cache

Use Redis for the Magento page and default cache

Prerequisite

Before you continue, install Redis.

Configure Magento to use Redis for default and page caching

Following is a sample configuration that causes Magento to use Redis for both the default cache (default array) and the full page cache (page_cache array). Magento’s caching is implemented by Magento\Framework\App\CacheInterface.

Add a configuration similar to the following to <your Magento install dir>app/etc/env.php:

'cache' =>
array(
   'frontend' =>
   array(
      'default' =>
      array(
         'backend' => 'Cm_Cache_Backend_Redis',
         'backend_options' =>
         array(
            'server' => '127.0.0.1',
            'database' => '0',
            'port' => '6379'
            ),
    ),
    'page_cache' =>
    array(
      'backend' => 'Cm_Cache_Backend_Redis',
      'backend_options' =>
       array(
         'server' => '127.0.0.1',
         'port' => '6379',
         'database' => '1',
         'compress_data' => '0'
       )
    )
  )
),

where

Parameter Meaning
default, page_cache Specify the segment name to use a particular segment or a default shortcut for all other caches.

The default cache segment enables you to configure all cache segments except for page_cache (the full page cache).

server Absolute URL to your Redis server, or 127.0.0.1 if Redis is installed on the Magento server, or an absolute path to a UNIX socket.
port Redis server listen port
database Required if you use Redis for both the default and full page cache. You must specify the database number of one of the caches; the other cache uses 0 by default.

Important: If you use Redis for more than one type of caching (for example, default cache and page cache), the database numbers must be different.

password Specifies a password if your Redis server requires authentication.
compress_data Required only for the full page cache. Set to 1 to compress the full page cache. Redis chooses a compression algorithm in the following order, based on availability: snappyl4z, or lzf. If none of them available, Redis uses gzip.

Basic verification

To verify that Redis and Magento are working together, use the following commands:

Redis monitor command

In a command prompt on the server on which Redis is running, enter:

redis-cli monitor

Refresh your storefront page and you’ll see output similar to the following.

Session storage

If you use Redis for session storage, you’ll see output similar to the following:

1476824834.187250 [0 127.0.0.1:52353] "select" "0"
1476824834.187587 [0 127.0.0.1:52353] "hmget" "sess_sgmeh2k3t7obl2tsot3h2ss0p1" "data" "writes"
1476824834.187939 [0 127.0.0.1:52353] "expire" "sess_sgmeh2k3t7obl2tsot3h2ss0p1" "1200"
1476824834.257226 [0 127.0.0.1:52353] "select" "0"
1476824834.257239 [0 127.0.0.1:52353] "hmset" "sess_sgmeh2k3t7obl2tsot3h2ss0p1" "data" "_session_validator_data|a:4:{s:11:\"remote_addr\";s:12:\"10.235.34.14\";s:8:\"http_via\";s:0:\"\";s:20:\"http_x_forwarded_for\";s:0:\"\";s:15:\"http_user_agent\";s:115:\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\";}_session_hosts|a:1:{s:12:\"10.235.32.10\";b:1;}admin|a:0:{}default|a:2:{s:9:\"_form_key\";s:16:\"e331ugBN7vRjGMgk\";s:12:\"visitor_data\";a:3:{s:13:\"last_visit_at\";s:19:\"2016-10-18 21:06:37\";s:10:\"session_id\";s:26:\"sgmeh2k3t7obl2tsot3h2ss0p1\";s:10:\"visitor_id\";s:1:\"9\";}}adminhtml|a:0:{}customer_base|a:1:{s:20:\"customer_segment_ids\";a:1:{i:1;a:0:{}}}checkout|a:0:{}" "lock" "0"

... more ...

Page caching

If you use Redis for page caching, you’ll see output similar to the following:

1476826133.810090 [0 127.0.0.1:52366] "select" "1"
1476826133.816293 [0 127.0.0.1:52367] "select" "0"
1476826133.817461 [0 127.0.0.1:52367] "hget" "zc:k:ea6_GLOBAL__DICONFIG" "d"
1476826133.829666 [0 127.0.0.1:52367] "hget" "zc:k:ea6_DICONFIG049005964B465901F774DB9751971818" "d"
1476826133.837854 [0 127.0.0.1:52367] "hget" "zc:k:ea6_INTERCEPTION" "d"
1476826133.868374 [0 127.0.0.1:52368] "select" "1"
1476826133.869011 [0 127.0.0.1:52369] "select" "0"
1476826133.869601 [0 127.0.0.1:52369] "hget" "zc:k:ea6_DEFAULT_CONFIG_CACHE_DEFAULT__10__235__32__1080MAGENTO2" "d"
1476826133.872317 [0 127.0.0.1:52369] "hget" "zc:k:ea6_INITIAL_CONFIG" "d"
1476826133.879267 [0 127.0.0.1:52369] "hget" "zc:k:ea6_GLOBAL_PRIMARY_PLUGIN_LIST" "d"
1476826133.883312 [0 127.0.0.1:52369] "hget" "zc:k:ea6_GLOBAL__EVENT_CONFIG_CACHE" "d"
1476826133.898431 [0 127.0.0.1:52369] "hget" "zc:k:ea6_DB_PDO_MYSQL_DDL_STAGING_UPDATE_1" "d"
1476826133.898794 [0 127.0.0.1:52369] "hget" "zc:k:ea6_RESOLVED_STORES_D1BEFA03C79CA0B84ECC488DEA96BC68" "d"
1476826133.905738 [0 127.0.0.1:52369] "hget" "zc:k:ea6_DEFAULT_CONFIG_CACHE_STORE_DEFAULT_10__235__32__1080MAGENTO2" "d"

... more ...

1476826210.634998 [0 127.0.0.1:52439] "hmset" "zc:k:ea6_MVIEW_CONFIG" "d" "a:18:{s:19:\"design_config_dummy\";a:4:{s:7:\"view_id\";s:19:\"design_config_dummy\";s:12:\"action_class\";s:39:\"Magento\\Theme\\Model\\Indexer\\Mview\\Dummy\";s:5:\"group\";s:7:\"indexer\";s:13:\"subscriptions\";a:0:{}}s:14:\"customer_dummy\";a:4:{s:7:\"view_id\";s:14:\"customer_dummy\";s:12:\"action_class\";s:42:\"Magento\\Customer\\Model\\Indexer\\Mview\\Dummy\";s:5:\"group\";s:7:\"indexer\";s:13:\"subscriptions\";a:0:{}}s:13:\"cms_page_grid\";a:4:{s:7:\"view_id\";s:13:\"cms_page_grid\";s:12:\"action_class\";s:43:\"Magento\\Catalog\\Model\\Indexer\\Category\\Flat\";s:5:\"group\";s:7:\"indexer\";s:13:\"subscriptions\";a:1:{s:8:\"cms_page\";a:3:{s:4:\"name\";s:8:\"cms_page\";s:6:\"column\";s:7:\"page_id\";s:18:\"subscription_model\";N;}}}s:21:\"catalog_category_flat\";a:4:{s:7:\"view_id\";s:21:\"catalog_category_flat\";s:12:\"action_class\";s:43:\"Magento\\Catalog\\Model\\Indexer\\Category\\Flat\";s:5:\"group\";s:7:\"indexer\";s:13:\"subscriptions\";a:6:{s:23:\"catalog_category_entity\";a:3:{s:4:\"name\";s:23:\"catalog_category_entity\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";N;}s:31:\"catalog_category_entity_decimal\";a:3:{s:4:\"name\";s:31:\"catalog_category_entity_decimal\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";s:71:\"Magento\\CatalogStaging\\Model\\Mview\\View\\Category\\Attribute\\Subscription\";}s:27:\"catalog_category_entity_int\";a:3:{s:4:\"name\";s:27:\"catalog_category_entity_int\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";s:71:\"Magento\\CatalogStaging\\Model\\Mview\\View\\Category\\Attribute\\Subscription\";}s:28:\"catalog_category_entity_text\";a:3:{s:4:\"name\";s:28:\"catalog_category_entity_text\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";s:71:\"Magento\\CatalogStaging\\Model\\Mview\\View\\Category\\Attribute\\Subscription\";}s:31:\"catalog_category_entity_varchar\";a:3:{s:4:\"name\";s:31:\"catalog_category_entity_varchar\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";s:71:\"Magento\\CatalogStaging\\Model\\Mview\\View\\Category\\Attribute\\Subscription\";}s:32:\"catalog_category_entity_datetime\";a:3:{s:4:\"name\";s:32:\"catalog_category_entity_datetime\";s:6:\"column\";s:9:\"entity_id\";s:18:\"subscription_model\";s:71:\"Magento\\CatalogStaging\\Model\\Mview\\View\\Category\\Attribute\\Subscription\";}}}s:24:\"catalog_category_product\";a:4:{s:7:\"view_id\";s:24:\"catalog_category_product\";s:12:\"action_class\";s:46:\"Magento\\Catalog\\Model\\Indexer\\Category\\Product\";s:5:\"group\";s:7:\"indexer\";s:13:\"subscriptions\";a:2:{s:23:\"catalog_category_entity\";a:3:{s:4:\"name\";s:23:\"catalog_category_entity\";s:6:\"column\"

... more ...

Redis ping command

Enter the following command:

redis-cli ping

PONG should be the response.

If both commands succeeded, Redis is set up properly.

More information

redis-cli command reference

Aws Ec2 인스턴스에 Redis 설치하기
Web Server

Aws Ec2 인스턴스에 Redis 설치하기

Click the link to read the original article: 읽으러 가기

===============

저는 Read cache를 위해 별도 EC2 인스턴스를 띄우고 redis를 사용하였습니다.

EC2 create

  • aws amazone linux AMI를 선택합니다.
  • security group 에 16379, 6379 포트를 추가합니다.
  • 인스턴스 생성완료

Linux updates

ssh로 접근해서 업데이트를 실행합니다.

$ sudo yum -y update
$ sudo yum -y install gcc make

Download Redis

참고: http://redis.io/download

$ cd /tmp
$ wget http://download.redis.io/releases/redis-4.0.0.tar.gz
$ tar xzf redis-4.0.0.tar.gz
$ cd redis-4.0.0
$ make

Create Directories and Copy Redis Files

$ sudo mkdir /etc/redis 
$ sudo mkdir /var/lib/redis
$ sudo cp src/redis-server src/redis-cli /usr/local/bin/
$ sudo cp redis.conf /etc/redis/

Configure Redis.Conf

conf 설정 파일을 수정합니다.

$ sudo vim /etc/redis/redis.conf

아래 내용 외 나머지 부분은 기본값을 유지합니다.

[..]
daemonize yes
[..]
  
[..]
bind 0.0.0.0
[..]
  
[..]
dir /var/lib/redis
[..]
  
logfile /var/log/redis_6379.log

Setting Redis-Server init script

참고: https://github.com/saxenap/install-redis-amazon-linux-centos

  • 자동 실행을 위한 스크립트를 다운 받습니다.
  • Redis-Server 파일 이동 후 권한을 설정합니다.
      $ sudo mv redis-server /etc/init.d
      $ sudo chmod 755 /etc/init.d/redis-server
      $ sudo vim /etc/init.d/redis-server
    	
      ->  redis="/usr/local/bin/redis-server" 확인
    
  • Redis-Server Auto-Enable 설정
      $ sudo chkconfig --add redis-server
      $ sudo chkconfig --level 345 redis-server on
    

Start Redis Server

드디어 서버를 실행합니다.

$ sudo service redis-server start
$ redis-cli ping -> PONG

강제 종료시
$sudo service redis-server stop
Redis, 레디스를 사용한 데이터베이스 캐싱서버 운영하기
Web Server

Redis, 레디스를 사용한 데이터베이스 캐싱서버 운영하기

Click the link to read the original article: 읽으러 가기

===========

Redis 서버의 구축 및 운영 등 여러가지 방안에 대하여 생각한 바를 정리한 내용이다. 먼저 Redis 서버가 필요한 이유는 무엇일까…

# Why Redis?

Redis를 왜 구축하는가를 아려면 Redis가 무엇인지부터 알아야한다.

! Redis란?Redis는 데이터베이스의 여러 솔루션 중 하나로 메모리를 사용하는 키, 밸류 형식의 데이터베이스이다. Redis의 최고 장점은 메모리를 사용하기 때문에 매우 빠른 속도를 자랑한다. 일반적인 하드 디스크에 비하여 상대적으로 엄청나게 빠를수도 있다. 다만 메모리라는 제약으로 공간이 크지 않고 키, 밸류(Key, Value) 형식의 입출력 방식이기에 복잡한 데이터베이스에 적합하지 않다.

위 내용만으로도 장점과 단점이 너무 극명하다. 빠르나 효과적인 주 데이터베이스로 사용하기에 다소 어려워보이는 점이다. 또한 공간이 많아질수록 비용이 급격히 올라가므로 이를 고려한다면 Redis는 빛좋은 개살구일 수 있다… 하지만! 대부분 Redis를 보조 데이터베이스 역할로 그 가치를 최대한 끌어내어 활용하고 있다. 그 중 Redis에 가장 적합한 것이 바로 데이터베이스 캐싱(Caching)이다.

! Caching Database Server캐싱(Caching)은 말 그대로 미리 읽어두었다가 요청이 올 경우 빠르게 응답하기 위한 목적으로 사용할 수 있다. 이 경우 전체 데이터가 필요없고 데이터 역시 계속 유지될 필요가 없기에 Redis처럼 적은 공간의 데이터베이스에 최적이다. 게다가 빠른 속도의 메모리를 사용하므로 잘 이용한다면 Redis 캐싱은 선택이 아닌 필수가 아닐까? 어찌보면 Redis는 캐싱을 위해 존재하는지도…

! 데이터베이스 캐싱… 꼭 필요한가?사실 이런 의문이 들 수도 있지만 모든 컴퓨터의 입출력 기술에는 알게 모르게 많은 부분이 캐싱되어 사용되고 있다. 메모리에 올려져 눈에만 안 보일 뿐 대부분이 이미 캐싱되어있지 않을까? 그렇다면 이번에는 웹서비스의 환경을 생각해보자. 아카마이나 CloudFront 등이 서버에서… 데이터베이스 역시 Redis Oracle의 TenTimes등에서 캐싱이 이뤄지고… 로컬 역시 다양한 방식으로 캐싱되며 localStoragesessionStorage를 사용해서도 클라이언트측 캐싱 서비스가 구축된다.

특히 대용량데이터나 컨넥션이 빈번하게 네트워크가 사용된다면 이에 따른 성능차이는 말로 표현하기 어렵다. 아키텍쳐에서 빠질 수 없는 부분이 바로 캐싱이며 어떻게 구축하고 운영하는가가 매우 중요하다.

# Redis 서버의 운영

여기까지 Redis의 장점과 필요성을 알아봤다면 이제 실제 운영을 위해 고민해보자. 일단 앞에 언급했듯이 Redis를 단독으로 주 데이터베이스로 사용하는 것은 무리가 있다. 텍스트 위주의 데이터라면 가능할 수 있으나 차라리 Expire 시점을 짧게 설정하는 편이 더 나을 것이다. 이는 뒤에 또 다루겠다.

어쨌든 Redis는 별도 서버로 구축되어 주서버와 지속적인 서비스를 주고 받는 방법이 효과적이다. 요즘은 하나에 모든 것을 관리 운영하기 보다 각각의 기능, 필요에 따른 마이크로 서비스(Micro Service) 형태로 많이 운영되어진다.

# CRUD에 따른 Redis 데이터 처리

Redis서버는 Client에서 Read 요청이 들어올때 주서버로부터 값을 가져와 저장한다. 이때 주서버와 싱크된 데이터 이 외에 추가로 데이터 만료시점을 처리하기 위해서 현재시간이나 만효시간을 함께 저장해야한다.

다음은 클라이언트의 Read 요청에 따른 처리과정으로 아래를 따르게 된다.

! Read 요청시– 방문자, 사용자의 새로운 데이터 서버에 요청
– Redis 서버에서 요청 데이터가 있는지 확인
– 데이터가 존재하는 경우 만료여부 확인 후 이 정보를 반환
– 정보를 반환한 경우 시간을 현재로 업데이트 후 종료
– 데이터가 만료되었거나 없는 경우 삭제 후 주 서버에 요청
– 주 서버에서 받은 데이터를 캐싱, 데이터베이스에 저장
– 이 값을 방문자에게 반환 후 종료

! CUD Create, Update, Delete 요청시이 경우 앞의 과정과는 조금 다르다. 그 이유는 데이터에 변화가 생겼으므로 해당하는 값의 데이터는 캐싱 값이 아닌 현재 실시간 정보를 보내주는 것이 효과적이기 때문이다. 캐싱 만료시간이 아무리 짧게 설정되어도 없는 데이터를 사용자가 보게되는 일으도록 해야할 것이다. 그러기 위해 필요한 조치는 비교적 간단하다. CUD 요청시 아래와 같이 처리한다.

– 방문자가 CUD를 서버에 요청
– CUD 요청을 주서버에 반영하여 업데이트
– 변경된 데이터 값을 캐싱데이터인 Redis에서 찾아 삭제 후 종료

여기서 가장 중요한 점은 캐싱을 제공하는 경우 단순하게 정보를 제공하는 주분만 고려하는 것이 아니라 다양한 상황에 대처해야한다는 점이다. 이 중 한 가지가 위와같이 CUD처럼 데이터에 중요한 변경사항이 있는 경우 기존의 캐싱 데이터를 삭제처리하는 과정이다.

! 마치면서여기까지 Redis 서버에 대하여 간략하게 알아보았다. 서비스를 구축할때 나도 이런 서비스를 제공한다라는 점보다 어떻게 제공하느냐가 매우 중요하다. 캐싱의 방법 역시 다양한 관점에서 고민하고 제공되어야 할 것이다.

! 추가내용위와같이 클라이언트 사용자의 요청에 따라 데이터를 만료하는 경우 요청이 없는 데이터가 불필요하게 오래 남을 수 있다. 이런 이유로 정기적인 시점… 특히 방문자가 적은 새벽 시점에 만료된 데이터를 clear하는 처리가 요구된다. 이런 작업은 Cron이나 AWS의 람다를 이용하는 것도 좋은 방법이다.

[Spring]스프링 프레임워크 설치하기-eclipse(1)
Web Server

[Spring]스프링 프레임워크 설치하기-eclipse(1)

[Spring]스프링 프레임워크 설치하기-eclipse(1)

[Spring]스프링 프로젝트 만들기-eclipse(2)

 

Click the link to read the original article:

=========================

자바를 하는 사람이 결국 한번은 거치게 되는 것이 spring프레임워크이다.

우리나라에서는 spring프레임워크는 자발 개발 표준 프레임워크이다.

필자는 빅데이터 수업을 들었는데 그 빅데이터 수업에서 강사님이 원래는 표준이 스프링이 아니였고

표준이 없어서 삼성은 삼성대로, LG는 LG대로 프레임워크를 썼다고 했다.

그러나 요즘은 스프링으로 통일되어 가는 분위기이다.

필자는 파이썬이(flask)나 nodejs(express)등의 프레임워크들을 접해봤다.

자바를 먼저배운것치고 자바 프레임워크를 오히려 늦게 배운편인데 spring은 조금 어렵다.

진입장벽이 있다는 말이다. spring의 명세는 저 프레임워크들보다 더 빡빡하고 더 체계적이다.

아마 오래되서 그런것일까? 아니면 필자가 잘 몰라서 그런것일까? 그건 잘 모르겠다.

어쨋던 spring을 제대로 알기위해서는 디자인패턴에대한 심도깊은 이해가 필요하다.

디자인패턴들을 그냥 아무렇지 않게 사용하는 경향이 있다.

예를 들어 spring의 근간을 이루는 mvc패턴은 말할것도 없으며

singleton, factory, dto, dao등의 패턴을 “이미 안다는 전제하”에서 시작한다.

따라서 spring을 쓰기위해서는 이 디자인패턴을 미리 알고 접근하는것이 매우매우매우 중요하다.

또한 spring은 jsp와 servlet을 근간으로 하기에 이 문법역시 알고 있어야하며

jdbc나 junit등의 표준에 가까운 라이브러리들도 알고 있어야하고

빌드 시스템인 maven(사실 메이븐이 강제는 아닌데 보통은 메이븐을 쓴다.)에 대해서도 이해해야한다.

그리고 깨알같이 알고 있어야하는 xml도 덤이다. 즉 spring프레임워크는 자바를 제대로 이해한 사람이

제대로된 프로젝트를 만들기위해서 사용하는 궁극의 비기(라고 말하면 개 중2병 같지만)같은 것이다.

결론부터 말하면 위에 것들을 모르면 그냥 배우지 말라는 것이다.

이들을 모두 알고 spring을 배우고 싶다면 필자의 Programming-Java-Spring의 강의를 보면된다.

여기서는 스프링 프레임워크를 사용하고 싶은 사람들은 어떻게 사용하면 되는지에 대해서 알려주는 강의이다.

스프링 프레임워크는 사실 설치라는 개념은 아니다. 그냥 jar파일을 추가하고 나면 자기 입맛대로 할 수도 있다.

근데 그렇게 하기엔 생산성도 너무 떨어지기에 그겋게 하는것을 추천하지는 않는다.

이클립스에서는 생산성을 위해서 sts라는 플러그인을 설치할 것이다.

Help->Eclipse Marketplace… 를 클릭해준다.

검색에서 sts를 타이핑해서 검색을하면 Spring Tool Suite를 다운받아준다.

다운을 하게되면 해당 라이브러리에 대한 설치가 진행된다.

이제 라이선스를 확인해준다.

이제 설치가 되는데 재시작을 해주면된다.

이제 다시 시작하면 스프링 프레임워크 대시보드가 추가된게 보인다. 이제 스프링 프레임워크를 사용할 준비가 되었다.

Install Apache Tomcat 8.0 and connect Eclipse
Web Server

Install Apache Tomcat 8.0 and connect Eclipse

Install Apache Tomcat 8.0 and connect Eclipse

Click the link to read the original article:

==============================

 » 프로그래밍+DB » Apache Tomcat 8.0 설치 + Eclipse 연결

Apache Tomcat 8.0 설치 + Eclipse 연결

이번에는 JSP, Servlet 사용을 위한 Tomcat 8.0 + Eclipse 연계 방법을 알아봄.

clip_image001

http://tomcat.apache.org/download-80.cgi 에서 Windows Service Installer 다운로드(8.0.x)

clip_image002

next

clip_image003

I Agree

clip_image004

Next

clip_image005

포트 확인 후 Next

clip_image006

Next

clip_image007

Install

clip_image008

Run Apache Tomcat… 조금 기다립니다.

clip_image009

알림 영역의 Apache Tomcat 9.0 아이콘을 더블클릭.

clip_image010

서비스를 중지합니다.

clip_image011

Eclipse에서 Window -> Open Perspective -> Other…

clip_image012

Java EE를 선택, OK

clip_image013

Window -> Preferences

clip_image014

Runtime Environments

clip_image015

Apache Tomcat v8.0 선택 후 Next

clip_image016

C:\Program Files\Apache Software Foundation\Tomcat 8.0

위 경로를 선택한 후, Finish

clip_image017

OK

clip_image018

Servers 탭에서 new server 생성

clip_image019

Tomcat v8.0 Server 선택 후, Next

clip_image020

Finish

clip_image021

Project Explorer의 Servers에 Tomcat v8.0 Server at localhost-config 가 추가되면 OK!

clip_image022

Dynamic Web Project 생성

clip_image023

test

clip_image024

새로 생성된 프로젝트의 WebContent에 HTML 파일 추가

clip_image025

index 입력, Finish

clip_image026

Hello World! 내용 추가

clip_image027

index.html -> Run As -> Run on Server

clip_image028

서버 선택 후 Next

clip_image029

우측에 test(프로젝트 이름)이 추가된 것을 확인 후, Finish

clip_image030

성공입니다. ^^

Windows에서 JDK와 Eclipse 설치, Java 프로젝트 만들기
Web Server

Windows에서 JDK와 Eclipse 설치, Java 프로젝트 만들기

Windows에서 JDK와 Eclipse 설치, Java 프로젝트 만들기

Click the link to read the article:

======

윈도에서 자바 프로그래밍을 하기 위해 JDK(Java Development Kit)를 설치하고 이클립스를 설치해 자바 프로젝트를 만드는 과정을 설명합니다.

JDK는 자바 프로그래밍 언어를 사용해 애플리케이션을 개발할 수 있게 해주는 개발 환경입니다.

개발할 일이 없는 일반 사용자는 JRE(Java Runtime Environment)만 있으면 자바 프로그램을 실행할 수 있습니다.

JDK에는 JRE + 개발에 필요한 것들(자바 컴파일러 javac.exe 등)이 있습니다.

이클립스는 애플리케이션 개발을 도와주는 무료 소프트웨어입니다.

 

목차

  1. 윈도에서 JDK 설치
  2. 이클립스 설치
  3. 자바 프로젝트 만들기

 

윈도에서 JDK 설치

jdk download를 검색해 가장 위에 나오는 오라클 사이트에 들어갑니다.

Java Download 버튼을 누릅니다.

라이선스 동의에 체크 후 현재 OS에 맞는 설치파일을 받습니다.

설치파일을 실행합니다.

설치 경로는 Program Files 아래 Java 폴더입니다.

 

이클립스 설치

eclipse를 검색하고 가장 위에 나오는 이클립스 사이트에 들어갑니다.

download 버튼이 잘 보입니다.

설치파일을 누르면 여러 종류의 IDE(통합 개발 환경)가 나오는데 그 전에 오른쪽 위의 !를 눌러 업데이트를 합니다.

라이선스에 동의해야 합니다.

저는 Java EE 용 IDE를 설치합니다.

처음 인스톨할 땐 오류가 났지만, 다시 시도하니 설치되었습니다. 실행해봅시다.

프로젝트를 만들면 아래 경로 아래에 만들어집니다.

계속 같은 경로를 사용할 테니 묻지 말라는 체크 표시를 하고 넘어갑니다.

처음에 나오는 창은 다시 안 뜨도록 체크하고 닫았습니다.

 

자바 프로젝트 만들기

File – New – Other…를 눌러 Java – Java Project를 만듭니다.

프로젝트 이름은 마음대로 적습니다. Finish를 누릅니다.

Java Perspective를 사용하면 자바로 개발할 때 있으면 좋은 창들이 배치된 화면이 구성됩니다.

창들은 개별 설정할 수 있으니 일단은 추천해주는 대로 사용합시다.

src 폴더에 자바 클래스 파일을 만들어봅시다.

오른쪽 클릭 – New – Class를 누릅니다.

아직 클래스들을 구별할 필요가 없으니 패키지 이름이 없다는 경고는 무시하고 클래스 이름만 넣습니다.

main() 메소드를 자동으로 만들도록 public static void main()에 체크합니다.

만든 클래스 파일에 간단한 println() 코드를 넣었습니다.

실행(Ctrl + F11) 또는 디버그(F11)하면 그 전에 저장하라는 알림창이 뜹니다.

항상 묻지 않고 저장 되도록 체크하고 OK 합니다.

Console 창에 성공적으로 출력이 되었습니다.

A/B Testing?
Web Server

A/B Testing?

A/B Testing?

Click the link to go to the original site.

=====

A/B testing이란?

A/B testing은 웹이나 앱에서 A버전과 B버전을 무작위로 유저들에게 보여주고 어떤 것이 나은지 실험하는 방법이다. 각 버전을 본 유저의 행동 데이터를 통계적으로 분석하여  특정한 변화를 주었을 때 목표를 더 높게 달성하는지 알아낼 수 있다.

사실 A/B testing은 오래전부터 과학에서 쓰여왔던 대조 실험(Controlled experiment)과 본질적으로 같다. 가설을 입증하기 위해 대조군(Controlled group)과 실험군(Experimental group)을 설정하고 결과를 검증하는 것은 과학적 방법론의 기본이다. A/B testing은 이 과학적 방법론을 인터넷 환경에 맞게 실행하는 것으로 볼 수 있다.

A/B testing은 웹/앱 기반 비즈니스라면 누구나 사용하고 있는 필수 도구다. 아마존, 구글, 넷플릭스 등 많은 기업들이 새로운 기능을 테스트하고 디자인을 최적화하기 위해 A/B testing을 활용하고 있다.

구글은 오래전부터 A/B testing을 적극적으로 활용해온 것으로 유명한데, 지금도 꾸준히 한 번에 50개 이상의 A/B test를 진행한다고 한다. 그러니 우리는 인터페이스가 약간 바뀌어도 알아채지 못하거나 신경 쓰지 않지만, 사실 A/B testing의 실험 대상이 되고 있을 수도 있다.

A/B testing이 중요한 이유는 가설을 직관이 아니라 데이터로 증명할 수 있기 때문이다. 사실 디자인에 대해서는 누구나 가설을 세울 수 있지만 증명하기는 어렵다. 만드는 사람 입장에서는 너무나 중요해보이지만 실제로는 아무런 행동을 이끌어내지 못한다거나, 전혀 예상치 못했는데 전환율이 크게 증가한다거나 하는 사례는 비일비재하다.

웹에서는 사용자들의 행동을 트래킹할 수 있기 때문에, 유저들이 실제로 어떻게 반응하는지 정량적으로 측정 가능하다. 실제 유저들의 심리와 행동을 파악하는 귀중한 자료가 되고, 이 피드백을 통해 서비스를 최적화해나갈 수 있다.

A/B testing으로 큰 효과를 낸 사례들을 몇 가지 보자. (Smashing Magazine을 참고했다.)

1. “I’m on twitter”보다 “You should follow Me on Twitter here”가 실제 팔로우 확률이 173% 높았다.

2. 회원가입 버튼 옆에 ‘It’s free!’를 넣으면 버튼을 누를 확률이 28% 증가한다.

3. 문장 스타일 정보 입력 폼을 사용하자 완료할 확률이 25-40%로 증가했다.

A/B testing은 만능이 아니다.

A/B testing은 아주 유용한 툴이지만, 모든 의사결정을 A/B testing으로 해결할 수는 없다. Diane Tang은 A/B testing course에서 이에 대해 “A/B testing은 산을 잘 올라가고 있는지는 말해주지만 어느 산에 올라가야 하는지는 말해주지 않는다.”라고 표현했다. 즉, A/B testing은 최적화 도구일 뿐 큰 그림을 보여주지는 못한다.

자..잠깐, 이 산 맞나?

그래서 A/B testing은 완전히 새로운 기능을 추가하거나, 훨씬 높은 단계의 의사결정에 관해서는 효과적이지 않다. 예를 들어 ‘유료로 이용할 수 있는 프리미엄 기능’을 추가한다거나, ‘현제 시작 페이지에 어떤 문제가 있는가?’ 같은 질문에는 대답하기 어렵다. 따라서 A/B testing을 실행할 때는 아주 구체적이고 명확한 기능, 디자인을 대상으로 하는 것이 좋다.

A/B testing은 웹 로그 분석, 사용성 테스트, 유저 인터뷰 등 보완적인 방법들을 함께 사용해야 한다. A/B testing은 정답을 유추해내는 하나의 단서일 뿐 그 자체가 정답은 아니다.

A/B tesing을 할 때 알아야 할 실험 윤리

Udacity의 A/B testing course(링크)에서는 한 챕터를 ‘Policy and Ethics of in A/B testing’에 할애하고 있다. 미처 생각해보지 못했던 부분이었다. 비록 불특정 다수를 대상으로 하지만 A/B testing도 실험의 일종이기 때문에 실험 과정에서 참가자를 보호할 의무가 있다. 다음 4가지 질문을 기억하자.

첫 번째, 참가자에게 어떤 위험이 따르는가?

‘참가자가 일반적인 일상생활에서 겪는 위험’을 최소 위험이라고 한다. 이를 기준으로 더 큰 위험이 따르는 경우 반드시 참가자의 동의를 얻어야 한다.

두 번째, 참가자들이 어떤 개인 정보가 수집되는지 알고 있는가?

실험 과정에서 민감한 정보를 수집하는 경우도 있다. 민감한 정보란 일반적으로 건강, 의료 데이터나 금융 데이터 등이 해당된다. 이런 정보가 수집되는 경우에는 정보 수집, 처리 과정에 대해 알리고 참가자의 동의를 받아야 한다.

세 번째, 개인 정보가 식별 가능한가?

프라이버시에 관해서 데이터는 다음과 같이 나뉜다.

식별 가능 데이터 (Identified data) : 특정 개인임을 알아낼 수 있는 정보. 이름, 아이디, 주민등록번호, 운전면허 번호, 휴대폰 번호 등이 해당된다.

익명 데이터(Anonymous data) : 식별 가능 정보가 없는 데이터

익명화된 데이터(Anonymous data): 재식 별 위험이 없도록 수정된 데이터

가명화 데이터 (Psuedonymous data) : 무작위로 생성한 쿠키 등을 통해 동일 데이터를 파악할 수는 있지만 개인 식별은 불가능한 데이터

각 데이터의 종류에 따라 프라이버시 보호의 정도가 달라진다. 법적 조항은 각 나라마다 다르다고 한다. 우리나라의 개인정보보호 가이드라인은 개인정보보호 종합포털을 참고.

네 번째, 데이터가 어떤 과정을 거쳐서 처리되는가?

처리 과정에서 어떤 사람들이 접근 권한을 가지고 있으며, 원래 목적으로만 사용되도록 보호하는 조치는 어떤 것이 있는가? 위반 시 어떤 조치를 하는가? 이런 질문에 대해서 미리 답변할 수 있어야 한다.


A/B testing 프로세스

1. 기존에 존재하는 데이터를 모으고 들여다본다.

웹 로그 분석이나 사용자 인터뷰 등 이미 가지고 있는 데이터들에 대해 충분히 이해해야 한다. 곧 설명하겠지만, A/B testing을 하기 위해서는 실험에 필요한 지표, 신뢰 수준, 표본 숫자 등등 많은 것들을 결정해야 한다.

이를 결정할 인사이트를 얻기 위해서는 기존 데이터에서 문제점은 무엇이 있는지, 어떻게 개선할 수 있을지, 지표들의 흐름은 어떠한지, 지표가 변동하는 범위는 어느 정도인지 등을 사전에 파악해야 한다. 유난히 이탈률이 높은 페이지를 찾아보거나, 트래픽이 유난히 높을 때는 언제인지 등등을 눈여겨보자.

2. 목표(Goal)를 구체화한다.

먼저 A/B testing을 통해 궁극적으로 이루고자 하는 목표가 명확해야 한다. 어떤 비즈니스를 하느냐에 따라 목표는 다 다를 수 있다. 예를 들어 취업 포털 사이트라면 ‘더 많은 사람들의 취직을 돕는 것’이 목표일 수 있고 가격 비교 사이트라면 ‘소비자들이 가장 싼 가격에 좋은 물건을 사게 하는 것’이 목표가 될 수 있겠다.

어느 정도 레벨을 목표로 잡느냐에 따라서도 다르다. 높은 수준의 목표라면 ‘더 많은 사람들의 취직을 돕는 것’ ‘유저가 싼 물건을 짧은 시간에 찾을 수 있게 하는 것’ 등이 될 수도 있고, 좀 더 구체적으로는 ‘채용 기업 회원 숫자’나 ‘회원 만족도’를 목표로 할 수도 있다.

목표를 세울 때 중요한 점은 ‘우선순위’의 관점에서 생각해야 한다는 것이다. 당연히 회원 수가 늘면 좋고, 매출이 늘어도 좋고, 만족도가 늘어도 좋다. 하지만 의미 있는 서비스를 만들기 위해서는 그중에서 팀이 가장 중요하게 생각하는 것이 반드시 합의되어야 한다.

다른 말로 하면 이 목표를 위해서는 다른 목표를 희생할 수도 있다는 점을 모두가 동의해야 한다. A/B testing에 있어서 ‘명확한 목표’는 실험을 효과적, 효율적으로 진행하기 위한 기본이다.

3. 지표(Metric)를 선정한다.

목표를 정했다면 그에 맞는 지표(Metric)를 선정해야 한다. A/B testing에서 좋은 지표를 선정하는 것은 아주아주 중요하므로 지표를 선정할 때는 신중하자.

3.1. 목표에 맞는 지표

지표를 선정할 때는 주로 퍼널 분석(Funnel Analysis)을 하게 된다. 퍼널 분석이란 특정 목표를 이루기 위해 필요한 이벤트를 단계적으로 나누어 분석하는 것을 말한다.  다음 단계로 넘어갈수록 깔때기처럼 좁아지기 때문에 퍼널(Funnel, 깔때기) 분석이라고 한다. 이 방법은 전환율(Conversion rate)을 계산함으로써 유저 행동을 단계별로 분석할 수 있기 때문에 유용하다.

서비스에서 유저들이 통과하는 퍼널을 단계적으로 분류해보고 이 과정에서 A/B testing로 개선이 필요한 지표를 선택한다. 1단계에서 기존 데이터를 살펴보았다면, 특별히 유저들이 많이 이탈하는 단계를 먼저 선정할 수 있다.

아니면 미리 설정한 ‘목표’에 가장 큰 영향을 주는 단계의 전환을 지표로 삼는 것도 좋다. 버튼을 클릭하는 것이나 이메일을 열어보는 것 등 측정할 수 있는 거라면 뭐든 지표가 될 수 있다.

3.2. 지표의 종류

지표의 종류는 크게 네 가지 카테고리가 있다.

첫 번째는 ‘웹사이트에 들어온 전체 유저의 숫자’와 같은 합계 지표(Sum)이다.

두 번째는 평균(mean)이나 중앙값(median)이다. 예를 들어 구매까지 걸리는 평균 시간(mean), 첫 구매가 발생할 때까지 방문한 페이지의 중윗값(median) 등이 있다.

세 번째는 확률(probability)이다. 어떤 이벤트가 발생한 경우 1, 아닌 경우 0을 부여해서  전체 확률을 볼 수 있다. 확률 지표는 항상 0과 1 사이에 위치한다.

마지막으로는 비율(Ratio)이 있다. 한 지표를 다른 지표로 나눈다. “결제하기를 누른 횟수 중 구매 완료한 횟수 / 결제하기를 누른 횟수” 같은 식이다.

3.3. 민감도와 강건성

지표를 결정할 때는 민감도(Sensitivity)와 강건성(Robustness) 두 가지를 반드시 고려해야 한다. 우리가 원하는 변화가 발생했을 때 그 변화에 비례해서 움직이는 지표를 민감(Sensitive)하다고 한다. 반대로 목표와 상관없는 변화가 일어났을 때 지표가 움직이지 않으면 강건(Robust)하다고 한다.

예를 들어서 이 ‘시간당 회원가입을 클릭한 횟수’가 지표라고 해보자.

먼저 강건성 체크를 위해 아무것도 바꾸지 않은 상태에서 회원가입을 클릭하는 횟수가 어떻게 변동하는지 본다. 그런데 지표를 보니 아무런 변화를 주지 않았는데도 ‘회원 가입 클릭 횟수’가 큰 폭으로 오르락내리락했다. 실험과 관련된 변화가 없는데도 들쑥날쑥하면 실험 결과가 왜곡될 수 있기 때문에 좋은 지표라고 할 수 없다.

반대로 우리의 목표인 ‘활동 유저 수(Active user)’가 늘어도 ‘시간당 회원가입을 클릭한 횟수’는 별로 변화가 없을 수도 있다. 이 경우에는 충분한 민감하지 못한 지표이기 때문에 역시 적합하지 않다.

기존 데이터나 아니면 작은 실험을 통해서 지표가 이 두 가지 조건을 만족하는지 테스트해보자.

3.4 지표의 정의

한 가지 더 주의해야 할 점은 testing을 하기 전에 지표를 엄밀하게 정의해야 한다는 점이다. 단순히 ‘클릭한 확률(Click-through-rate)’이 지표라고 하더라도 impression을 기준으로 할지, 페이지뷰를 기준으로 할지에 따라 완전히 다르다. ‘클릭한 순간을 트래킹할지 클릭하고 다음 페이지로 이동했을 때 트래킹할지’ 같이 사소해 보이는 문제도 실제 웹상에서는 구현할 때는 완전히 다를 수 있다. 지표를 수식으로 나타내 보고 각 요소를 하나하나 따져보자. 테스팅을 구현하는 개발자와 원활한 소통을 위해서는 지표를 최대한 엄밀하게 정의하는 것이 좋다.

4. 가설을 수립한다.

목표와 지표가 있다면 이제 어떤 변화를 주어야 이 지표가 향상될 수 있을지, 그리고 왜 그럴지에 대해 가설을 세운다.

예시) “결제 페이지를 세 단계에서 두 단계로 바꾸면 결제하기를 클릭한 사람 중 완료한 사람의 비율이 높아질 것이다. 결제 단계가 간단하면 중간에 포기하고 나가는 고객이 줄어들 것이기 때문이다.”

유저 행동에 영향을 미치는 요소라면 무엇이든지 A/B testing 대상이 될 수 있다. 헤드라인, 텍스트, 사용후기, CTA(Call to Action) 버튼, 링크, 이미지, 접기 버튼, 기사 스크랩, 페이지 레이아웃 등등.

여러 가지 가설이 리스트에 있다면 예상되는 효과의 크기와 실행 난이도에 따라서 우선순위를 매기면 된다. 효과가 크고, 실행하기 쉬운 가설부터 실험한다.

5. 실험을 설계한다.

5.1. 분기 단위(Unit of diversion)

먼저 분기 단위(Unit of diversion)를 정해야 한다. 분기 단위(Unit of diversion)는 A그룹(대조군)과 B그룹(실험군)을 나누는 기준을 말한다. 주로 사용되는 3가지는 ID, cookie, event다.

ID의 경우, 로그인이 된 회원의 ID를 기준으로 대조군, 실험군을 나눈다. ID를 사용하면 동일 유저가 시간차를 두고 나중에 다시 접속하거나, 디바이스를 웹에서 모바일로 바꾸더라도 환경이 바뀌지 않아 일관적이다. 하지만 로그인을 하기 전에는 분기를 할 수 없고, 개인 식별이 가능하기 때문에 데이터 수집 시 주의해야 한다.

Cookie란 사용자가 사이트를 방문할 때 생성되는 기록 파일이다. 로그인을 하지 않아도 사용자의 행동을 트래킹 할 수 있다는 장점이 있다. 그래서 웹사이트에 들어가면 “쿠키 정보를 수집합니다”라고 알림이 뜨는 이유다. 다만 브라우저나 디바이스가 바뀌거나 쿠키가 삭제되면 트래킹이 불가능하다는 단점이 있다.

Event을 사용하면 유저가 어떤 행동(event)을 했을 때 무작위로 A 혹은 B의 결과가 나타나게 된다. 즉 ‘회원가입 클릭’이라는 이벤트를 기준으로 한다면, 매번 회원가입을 클릭할 때마다 A 화면이 뜰 수도 있고 B 화면이 뜰 수도 있다. 이 경우 동시에 서비스의 일관성을 많이 해칠 수 있다. 대신 가장 임의화된 (Randomized) 샘플을 뽑을 수 있어서 통계적으로 효과적이라는 장점이 있다.

따라서 Event 분기는 유저가 눈치채기 어려운 A/B testing일 때만 쓰인다. 예를 들어 ‘동영상 로딩 속도’를 높였을 때 ‘동영상을 끝까지 보는 사람의 비율이 늘어나는지 확인’하고 싶다고 하자. 동영상을 클릭했을 때 랜덤으로 ‘로딩 시간 0.5초’ 혹은 ‘로딩 시간 2초’가 나타나는 것이다. 이런 변화의 경우 유저가 알아채기 거의 힘들다. 즉, 유저가 “아니 어떨 때는 0.5초가 걸리고 어떨 때는 2초가 걸리는 거야?”라고 불만을 가지지 않는다는 말이다. 그래서 이럴 때는 Event 분기를 사용해서 A/B testing을 할 수 있다.

한 가지 더 고려해야 할 점은 분석 단위(Unit of analysis)이다. 분석 단위란 간단히 말해 지표의 분모다. 지표가 ‘회원당 구매액’이라고 해보자. 수식은 다음과 같을 것이다.

총 구매액 합계 / 회원 수

이 지표에서 분석 단위는 분모인 ‘회원’이 된다. 즉, A/B testing으로 영향을 주려고 하는 최소 단위다.

분기 단위를 정할 때는 분석 단위와 일치시키는 것이 바람직하다. ‘회원당 구매액’의 경우 분석 단위가 ‘회원 한 명’이므로 ID를 기준으로 분기한다. 분기 단위와 분석 단위를 일치시키는 이유는 실험 데이터를 ’독립 사건’으로 만들기 위해서다. 예를 들어 우리가 분석하고 싶은 단위는 ‘회원’인데 실험 데이터에서는 ‘페이지뷰’로 분기되어있다면, 한 명은 회원이 여러 개의 페이지뷰를 만들어낼 수 있다. 그러나 각 페이지뷰는 한 명의 회원이 만들어낸 것이므로 서로 확률이 연관되어있고, 사건 간의 독립성이 없다. 따라서 어떤 회원은 페이지뷰를 100번 했고, 어떤 회원은 페이지뷰를 1번 했을 때 실험 데이터가 왜곡될 가능성이 커진다. ‘통계적으로 유의미’ 한 결과가 나오기 힘들어진다. ‘통계적 유의성’에 관해서는 5단계에서 알아보겠다.

5.2. 목표 집단 (Target Population)

일반적으로 실험을 할 때는 샘플 숫자가 많을수록 좋다. 결과의 신뢰도가 올라가기 때문이다.

그럼에도 불구하고 무작정 모든 유저를 모집단(Population)으로 잡고 샘플링하면 오히려 신뢰도를 떨어뜨릴 수 있다. 어떤 상황에서는 측정하려고 하는 변화가 특정 집단에게만 의미 있는 것일 수 있기 때문이다.

예를 들어 홈페이지에 한국어 폰트를 변경하는 테스트를 했을 경우, 이 변화의 영향을 받는 유저는 한국 유저다. 그런데 이를 고려하지 않고 외국 유저까지 포함된 전체 유저를 대상으로 샘플링을 할 경우, 한국어 폰트 변경이 효과가 있었음에도 불구하고 영향을 받지 않는 그룹(외국 유저) 때문에 데이터를 분석했을 때  ‘효과 없음’으로 결론날 수가 있다. 한국 유저들의 행동 변화를 외국 유저들이 상쇄시키기 때문이다.  따라서 실험의 대상이 되는 모집단을 정확히 정의하자.

코호트(Cohort)를 기준으로 A/B testing을 할 수도 있다. 코호트란 ‘특정 기간 특정 경험을 공유한 사람들의 집합’을 말한다. 예를 들면 ‘앱 설치’가 기준이라면 4월에 앱을 설치한 그룹, 5월에 앱을 설치한 그룹 이런 식으로 나누는 방법이다. 코호트 분석은 유저 행동을 분석할 때 널리 쓰이는 방법이다. 웹/앱 서비스를 사용한 시간에 따라서 사용자의 패턴이 달라지기 때문이다. 서비스를 사용한 지 1개월 된 유저와 3년 된 유저는 특성이 매우 다를 수밖에 없다.

A/B testing에 코호트를 적용하는 이유는 여러 가지가 있다. 그중 하나는 ‘학습 효과’를 없애기 위해서다. 서비스에 변화가 생기면 유저들이 처음에는 익숙하지 않다가 차차 변화에 적응하는 것을 학습 효과라고 부르는데, 학습 효과가 진행되는 기간에는 데이터가 튀거나 왜곡될 수 있다. 실제로는 긍정적인 변화라도 기존 방식에 익숙해져 있던 유저들에게는 단기적으로 안 좋은 지표 변화가 나타날 수 있기 때문이다. 코호트를 사용해 새로 서비스를 사용하기 시작한 유저들을 대상으로만 A/B testing을 사용하는 식으로 ‘학습 효과’를 데이터에서 배제할 수 있다.

이 외에도 유저 리텐션(Retention) 향상이 목표이거나, 가입 시점에 따라서 실험 결과가 영향을 받을 수 있는 A/B testing의 경우는 목표 집단을 특정 코호트로 제한하는 방법이 효과적이다.

5.3. 표본 크기(Sample Size)

의미 있는 결과를 내기 위해 필요한 표본 숫자(n)가 얼마인지 알아야 한다. 필요한 표본 숫자는 신뢰도 수준을 더 보수적으로 잡거나, 오차 범위 구간을 작게 잡거나, 현실적으로 유의미한 변화(6.3.에서 설명)를 낮게 설정할수록 늘어난다.

각 수치들은 트레이드오프 관계이기 때문에 우선순위를 정하기 나름이다. 신뢰도가 높은 결과를 얻고 싶다면 표본 숫자를 늘려야 하고, 표본 숫자를 많이 구하기가 힘들다면 그만큼 신뢰 수준이 낮거나 오차 범위가 커진다.

우선순위를 고려해서 수치를 결정했다면 표본 숫자 계산은 어렵지는 않다. A/B testing 프레임워크를 쓴다면 대부분 자동으로 탑재되어있으며, 아니면 구글에서 ‘A/B testing sample size calculator’라고만 검색해도 쉽게 찾을 수 있다.

5.4. 실험 기간(Duration)

실험 기간도 결정해야 한다. 시간은 금이기 때문에 일단 기간은 최대한 짧은 게 좋겠지만, 기간이 짧은 경우 정확성을 놓칠 수가 있다. 전문가들은 A/B testing기간은 최소 수 일 이상은 되어야 한다고 조언한다. 결과에 영향을 미칠 수 있는 외부 변수들이 많이 있기 때문이다. 트래픽은 특정한 날짜나 요일에 따라서 영향을 받는다. 특히 E-commerce 사이트의 경우 명절, 연휴 기간에는 평소와 전혀 다른 패턴이 나타날 수 있다. 이런 경우가 실험에 영향을 주지 않도록 고려해서 기간을 정해야 한다. 또는 구매 주기가 긴 상품(가구, 자동차 등)의 경우에는 효과가 나타날 때까지 시간이 걸린다. 현실적으로 가능한 선에서 충분한 기간을 갖고 실험하자.

6. 결과를 분석한다.

이제 실험에서 도출된 데이터를 보고 결론을 도출해야 한다. 지표가 긍정적으로 변했다고 해서 흥분하지 말자. A/B testing을 할 때 가장 흔하게 나타나는 실수다. 실험 과정에서 무언가 잘못되었을 수도 있고, 우연의 일치가 일어났을 수도 있다. 그러므로 실제로 이 결과가 정말로 의미 있는지 알려면 3단계 확인을 해야 한다.

6.1. 불변 지표(Invariant Metric)

먼저 실험 과정에서 문제점이 없었는지 재점검을 해보기 위해서 불변 지표(Invariant metric)가 변하지 않았는지 체크한다. 불변 지표란 실험 과정에서 변하면 안 되는 변수다.

예를 들어 표본 숫자는 실험군과 대조군 사이에 큰 차이가 나서는 안된다. 기본적으로 A/B testing에서는 50대 50 확률로 실험/대조군을 분류하게 된다. 전체 트래픽을 2분의 1로 딱 나누는 것이 아니기 때문에 실험/대조군의 표본 숫자에 차이가 나는 것이 정상이다. 하지만 오차 범위를 계산해봤을 때 그 이상으로 차이가 난다면 실험 과정에서 뭔가 잘못되었을 가능성이 있다.

그 외에도 가설과 관련 없는 지표가 변화(회원가입 버튼을 바꾸었는데 결제 페이지 지표가 크게 바뀌었다던지) 하지 않았는지 확인하자. 시스템 상에서 오류가 일어나는 경우는 흔하고, 아니면 다른 외부 변수가 작용했을 수 있다.

A/A testing은 실험이 제대로 진행되었는지 확인할 때 유용하다. A/A 테스트란 아무런 변화도 주지 않고, 두 집단의 차이를 측정하는 실험이다. 즉, A/A 테스트를 했을 때는 양쪽 집단에서 결과가 똑같이 나와야 정상이다. 그렇지 않다면 뭔가 문제가 있는 것이다. 체중계로 치면 영점 조정이라고 할 수 있겠다. 올라가기 전에 정확하게 0에 맞춰져 있어야 측정 결과를 신뢰할 수 있는 것과 같은 원리다. Diane에 따르면 구글에서는 A/B 테스팅 전후에 A/A 테스트를 반드시 하도록 내부적으로 정해져 있다고 한다.

6.2. 통계적 유의성 (Statistical significance)

어떤 실험 결과를 두고 ‘통계적으로 유의미하다’고 하는 것은 단순히 우연이라고 보기 어렵다는 뜻이다. 실험에서는 언제나 우연의 가능성이 있기 때문에, 통계적으로 유의미한 결과인지 확인하는 것은 아주아주 중요하다.

통계적으로 유의미하다는 말은 동시에 이 실험을 다시 한번 해도 똑같은 결과가 나온다는 말이기도 하다. 우리는 A/B testing을 통해서 가설을 입증하고 이를 서비스 전체에 적용하고 싶은 것이기 때문에, 이 결과를 반복해서 나타날 수 있는지 여부를 반드시 점검해야 한다.

이 과정을 통계학에서는 가설 검정(hypothesis test)이라고 한다. 가설 검정을 모두 설명하게 되면 관련된 통계학 이론에 대해서 설명해야 하기 때문에 나중에 이 부분에 관해서 따로 정리해보겠다.

결론만 말하자면, Hypothesis testing을 통해서 변화가 ‘우연히 일어났을 확률’을 구할 수 있는데, 일반적으로 이 확률이 5% 이하이면 통계적으로 유의미한 것으로 본다.

6.3. 현실적 유의성 (Practical significance)

통계적으로 유의미한 결과가 나왔다고 하더라도 바로 그 가설을 적용해서는 안된다. 이 실험 결과를 전체적으로 적용하기 위해서는 시간과 돈이 들기 때문이다. 따라서 현실적으로 유의미하다는 말은 비용과 시간을 고려했을 때도 충분히 실행할 가치가 있는 가설이라는 뜻이다. 따라서 이는 상황을 고려해서 직접 결정해야 한다. 어떤 비즈니스냐에 따라 범위가 다를 수 있다.

극단적인 예로 신약 개발의 경우, 신약의 성능이 15% 이상은 되어야 현실적으로 유의미한 숫자라고 한다. 제품화에 그만큼 많은 시간과 비용이 들기 때문이다. 하지만 웹/앱 서비스 경우에는 그렇지 않기 때문에 1-2% 정도만 되어도 굉장히 의미 있는 차이로 본다.

‘왜’를 놓치지 말자

실험 결과가 이 3가지 점검을 모두 통과했다면 가설을 전체 서비스에 적용할 수 있다. 하지만 한 가지 더 마지막으로 유의해야 할 점이 있다. 단순히 가설을 입증했다고 해서 끝은 아니다.

왜 그런 결과가 나왔는지에 대한 이유를 더 파고 들어가야 한다. A/B testing은 유저 행동이 변화한 이유까지는 알려주지 않기 때문이다. 입증된 가설을 가지고 유저 인터뷰 등 정성적인 분석 방법을 통해서 유저에 대해 깊게 이해해나가야 지속적으로 사랑받는 서비스를 만들어갈 수 있다.


이 글은 Udacity의 A/B testing 강의 내용을 재구성했습니다.

How to detect and clean malware from your Linux server using Maldet
Magento 2

How to detect and clean malware from your Linux server using Maldet

How to detect and clean malware from your Linux server using Maldet

Click the link to the article page:

=============

What is Malware?

Malware is the short form of Malicious Software. Any software that is introduced into your system/server with the malicious intent of disrupting the smooth operation of your server, to collect sensitive private information or to gain access to your system is malware.

How can you recognize the presence of malware?

You may or may not recognize that there is a malware attack on your system for a long time. Sometimes, your readers may report a warning from an anti-virus software like this.

Sometimes, Google Webmasters or Bing Webmasters will report it.

Either way, when you are alerted of malware, the first step would be to secure your system. Cleaning up may be futile if your system is not secure. So, secure first. Take backups of your files and databases. Change all passwords and then go on to cleaning the system of malware.

Most importantly, you need not wait to react after a malware attack. You can set up malware scanning as a regular check proactively so as to be able to catch them as soon as possible.

Linux Malware Detect (LMD)

Linux Malware Detect (LMD), popularly known as Maldet is an open-source malware scanner for Linux released under the GNU GPLv2 license. It is designed around the threats faced in shared hosted environments. Install, configure and run this free software to detect and clean malware on your system.

Install maldet and configure

Installation

Login as root or an account with root permissions into your server.

The source code of the current stable version of LMD or maldet is available as a tar ball at this link. Download it.

    sudo wget http://www.rfxn.com/downloads/maldetect-current.tar.gz

Unpack the tar ball.

    sudo tar -xvf maldetect-current.tar.gz

After this, list the files to see the directory in which it is installed. The directory is usually of the format maldetect-x.y.z where x.y.z is the version number. Change to this directory.

    cd maldetect-1.5

Check if the install.sh script is there and run it.

    sudo ./install.sh

The installation is complete.

Configuration

For configuring maldet, the configuration file at /usr/local/maldetect/conf.maldet has to be edited.

Open it with a text editor.

The following are some of the common options that you may want to set.

If you want to be alerted of the presence of malware by mail, set the following options.

  • email_alert : If you want to get email alerts whenever a suspicious file is detected, then it should be set to 1.
  • email_addr : The email address to which alerts should be sent. This is used in conjunction with the email_alert option.
  • email_ignore_clean : When malware alerts have been automatically cleaned (check the next two options), ignore sending email alerts. This is disabled by default. Set it to 1 to enable it, if you have set up an automated daily scan that detects and cleans the hits and you do not want to be alerted of these by mail.

What action should be taken on the affected files? The following options can be set to quarantine (to move the affected files to a secure location where they cannot produce any harm) the files.

  • quarantine_hits : The default value is 0. Set this to 1 so that the affected files will be moved to quarantine.
  • quarantine_clean : The default value is 0. This is used when quarantine_hits is set to 1. Do you want the system to further clean the files? Set this to 1 if you want the system to try to clean the malware injections. Keep this as zero if you want to inspect before cleaning.

In a multi-user environment, the following options may be useful.

  • quarantine_suspend_user : By default, this is disabled and set to 0. If you set this to 1, the accounts of users who have hits will be suspended. For this to work, quarantine_hits should be 1.
  • quarantine_suspend_user_minuid : The minimum user id which can be suspended. This is set to 500 by default.
  • inotify_minuid : The minimum user id above which users need to be monitored. The default value is 500 (more details here).
  • inotify_docroot : The web directory relative to the home directory of users. By default, it is set to public_html. If this is set, only this web directory will be monitored.

Save and close the configuration file.

Scanning and its options

A basic scan

For a basic scan, run maldet with the --scan-all option with a path as an argument. It first builds a list of files in all the directories and sub-directories in that path. Then it scans through all the files and gives the number of hits. It also gives a report which you can view to inspect the files that are suspicious. Make sure that you give the full path and not the relative path.

    sudo maldet --scan-all /home/username/public_html/

A note of caution, though. The setting scan_ignore_root in the configuration file is set to 1 by default. This causes files that are owned by root to be ignored in the file list that maldet builds. The default value is more efficient, but the assumption is that your root password has not been compromised and malware are not injected into root-owned files. Change this setting to 0 if you want root-owned files also to be scanned. This might slow down the scan. So, use it judiciously.

You can view the files that are affected by opening the report file mentioned.

Quarantine affected files

When quarantine_hits is set to 1, maldet not only scans for malware, but also moves the hits to a quarantine so that your users do not have access to these files. So, your malware scan may produce results as below. In this case, quarantine_clean is set to 0.

If you view the report, you can see the affected files and their quarantine location. You can inspect the files and then decide on whether you want to clean them.

If you performed a scan with the quarantine_hits set to 0, you need not set it to 1 and redo the scan (as shown above). Instead, you could quarantine all malware results from the previous scan with

sudo maldet –quarantine SCANID

Quarantine and clean affected files

When quarantine_clean is set to 1, in addition to moving the affected files to quarantine, maldet also tries to clean them.

If you did a scan with the quarantine_hits or quarantine_clean set to 0, you can do a clean with the following option.

    sudo maldet –clean SCANID

Restore a file

If you want to restore a file which was wrongly tagged as a malicious and quarantined, or if you have manually cleaned the file and want it back in its proper location,

    sudo maldet –restore FILENAME

Alternately, give the complete path of the quarantined file.

    sudo maldet –restore /usr/local/maldetect/quarantine/FILENAME

Wildcard scan

You can also use wildcards in your scan path. ? is the wildcard character.

    sudo maldet --scan-all /home/?/public_html/

This would check all directories inside /home and if any of them had a public_html sub-directory, then that directory will be scanned completely.

Recent scan

If you want to scan the same path as a previous scan, but only those files created or modified in the recent past, you have to run maldet with the --scan-recent option and the number of days n

    sudo maldet --scan-recent /home/username/public_html/ 7

A weekly incremental check can be done by doing such a recent scan for 7 days.

Automate periodic scan

You can automate daily scans using the cronjob feature. During installation, LMD installs a cronjob at /etc/cron.daily/maldet.

This cronjob (an automated job that runs periodically) will update signatures, include new malware threats in its registry and perform a daily scan of all the home directories and recent changes on the server. Whenever, it detects some malware, it will notify you at the mail address specified in the configuration.

Monitor mode

The inotify monitor can be used to monitor users real-time for file creation, modification or movement. Monitoring can be done with one or more of the three options available,

Monitor users

The users option will take the home directories of all users in the system who have uid greater than inotify_minuid and monitor them. If inotify_docroot is set, the users’ web directory, if it exists, will only be monitored.

    sudo maldet --monitor users

Monitor paths

Alternately, you can monitor paths. Give a comma separated list of paths with the --monitor option.

    sudo maldet --monitor PATH1,PATH2,...PATHN

For example,

    sudo maldet --monitor /tmp,/home,/var

Monitor files

If you have concerns about specific files, you can monitor specific files by giving a comma-separated list of files.

    sudo maldet --monitor FILE1,FILE2,...FILEN

Exclude files or paths

Certain paths or files can be excluded from scan, by using the ignore files.

Add files or paths to be excluded (one per line) from daily scan in /usr/local/maldetect/ignore_paths

Add signatures to be excluded (one per line) from daily scan in /usr/local/maldetect/ignore_sigs

Add files or paths to be excluded from inotify monitoring (one per line) in /usr/local/maldetect/ignore_inotify.

Add the extensions of file types that you want to exclude from daily scans (one per line) in /usr/local/maldetect/ignore_file_ext. Sample entries in file could be

    .png
    .jpg

Check out more options like running maldet in the background and other finer settings by using the help option.

    sudo maldet --help

If you run a self-hosted website, at some point or the other, it is possible for malicious hackers to inject malware into your system. Before that happens, get your system secure and install maldet to keep ahead of such attacks.

(For the purpose of this tutorial, Ubuntu version 14.04 and maldet version 1.5 were used)

RESTful API란 ?
Web Server

RESTful API란 ?

RESTful API란 ?

Click the link to see the article:

개발 공부를 시작하고 자주 접하고 그냥 지나친 개념 중에 하나이다. 면접 질문으로도 자주 나온다고 하고, 실제로 채용공고 필요 역량에도 REST 등 인터넷 기반 프로토콜/ 기술에 대한 이해를 요구하고 있는 기업도 다수 있다.


REST하다는 것은 무엇일까?


REST(REpresentational State Transfer) ‘대표적인 상태 전달’ 흠.. 무슨 말인지 와닿지 않는다.

REST란, “웹에 존재하는 모든 자원(이미지, 동영상, DB 자원)에 고유한 URI를 부여해 활용”하는 것으로, 자원을 정의하고 자원에 대한 주소를 지정하는 방법론을 의미한다고 한다.

따라서 Restful API는 REST 특징을 지키면서 API를 제공하는 것을 의미한다. (일종의 Coding Convention이랄까. 설계원칙, 가이드를 지키면서 개발을 하자는 의미인듯 싶다.)

그렇다면 왜 REST 개념이 대두되었을까?

큰 특징으로는 ‘애플리케이션 분리 및 통합’, ‘다양한 클라이언트의 등장’이다.

애플리케이션의 복잡도가 증가하면서 애플리케이션을 어떻게 분리하고 통합하느냐가 주요 이슈가 되었고, 이에 자바 진영에서는 과거 EJB(Enterprise Java Beans), SOA(Service Oriented Architecture)에 이어 최근에는 MSA(Micro Service Architecture)와 함께 REST가 떠오르고 있는 것이다.

그리고 모바일과 같은 다양한 클라이언트의 등장하면서 Backend 하나로 다양한 Device를 지원하기 위해 REST의 필요성이 증대되었다.


그래서 REST란 무엇일까?


REST 구성– 자원 (Resouce) – URI– 행위 (Verb) – HTTP Method– 표현 (Representations)


예) /users GET /users/{id} GET /users PUT
REST의 특징1) Uniform (유니폼 인터페이스) : HTTP 표준에만 따른다면, 안드로이드/IOS 플랫폼이든, 특정 언어나 기술에 종속되지 않고 모든 플랫폼에 사용이 가능하며, URI로 지정한 리소스에 대한 조작이 가능한 아키텍처 스타일을 의미한다.
2) Stateless (무상태성) : HTTP는 Stateless Protocol 이므로, REST 역시 무상태성을 갖는다. 즉, HttpSession과 같은 컨텍스트 저장소에 상태정보를 따로 저장하고 관리하지 않고, API 서버는 들어오는 요청만을 단순 처리하면 된다. 세션과 같은 컨텍스트 정보를 신경쓸 필요가 없어 구현이 단순해진다.
3) Cacheable (캐시가능) : HTTP 기존의 웹 표준을 그대로 사용하므로, 웹에서 사용하는 기존의 인프라를 그대로 활용 가능하다. HTTP 프로토콜 기반의 로드밸런서(mod_proxy)나, SSL은 물론이고 HTTP가 가진 가장 강력한 특징 중의 하나인 캐싱 기능을 적용할 수 있다. 일반적인 서비스에서 조회 기능이 주로 사용됨을 감안하면, HTTP 리소스들을 웹 캐쉬 서버 등에 캐싱하는 것은 용량이나 성능 면에서 이점이 있다. 캐싱 구현은 HTTP 프로토콜 표준에서 사용하는 Last-Modified 태그나 E-Tag를 이용하면 가능하다.

캐시란 무엇인가?(펼치기)

 
E-Tag : 메시지에 담겨있는 엔터티를 위한 엔터티 태그를 제공한다. 이를 활용하여 리소스를 식별할 수 있다.
Last-Modified : 엔터티가 마지막으로 변경된 시각에 대한 정보를 제공한다. (파일인 경우 파일 시스템이 제공해 준 최근 변경 시각, 동적으로 생성된 리소스라면 응답이 만들어진 시간)

4) Self-descriptiveness (자체 표현 구조) : 동사(Method) + 명사(URI) 로 이루어져있어 어떤 메서드에 무슨 행위를 하는지 알 수 있으며, 메시지 포맷 역시 JSON을 이용해서 직관적으로 이해가 가능한 구조로, REST API 메시지만 보고도 이를 쉽게 이해할 수 있다. 5) Client – Server 구조 : REST 서버는 API 제공, 클라이언트는 사용자 인증이나 컨텍스트(세션, 로그인 정보 등)을 직접 관리하는 구조로 각각의 역할이 확실히 구분되기 때문에 클라이언트와 서버에서 개발해야 할 내용이 명확해지고 서로간 의존성이 줄어들게 된다.
6) 계층형 구조 : API 서버는 순수 비지니스 로직을 수행하고, 그 앞단에 사용자 인증, 암호화(ssl), 로드밸런싱 등을 하는 계층을 추가하여 구조상의 유연상을 둘 수 있다. 이는 간단하게는 HA Proxy나 Apache의 Reverse Proxy를 통해, 더 나아가서는 API gateway 등을 활용하여 Micro Service Architecture로도 구현이 가능하게 한다.


REST 요소를 파악하는데는 Richardson Maturity Model(RMM)을 기준으로 이해하는 것이 좋은 것 같다.


레벨0

웹의 기본 메커니즘을 전혀 사용하지 않는 단계로, HTTP를 통해 데이터를 주고받지만 모든 데이터 요청 및 응답과 관련한 정보를 HTTP의 body 정보를 활용한다.

POST /appointmentService HTTP/1.1

[various other headers]

<openSlotRequest date = "2010-01-04" doctor = "mjones"/>

POX(Plain Old XML)로 요청과 응답을 주고받는 RPC 스타일 시스템이다. 이 때 HTTP method는 POST만 사용하며, 특정 서비스를 위해 클라이언트에서 접근할 endpoint는 하나이다.


레벨 1 – 리소스

RMM에서 REST를 위한 첫 단계는 리소스를 도입하는 것이다. 그래서 이제는 모든 요청을 단일 서비스 endpoint로 보내는 것이 아니라, 개별 리소스와 통신한다.

POST /doctors/mjones HTTP/1.1

[various other headers]

<openSlotRequest date = "2010-01-04"/>

즉, 함수를 호출하고 인자들을 넘기는 것이 아니라 다른 정보를 위해 인자들을 제공하는 특정 리소스로 요청을 보낸다. 이럴 경우의 이점은 자원이 외부에 보여지는 방식과 내부에 저장되는 방식을 분리 할 수 있다는 것이다. 예를 들면 클라이언트 단에서 완전히 다른 포맷으로 저장하더라도 JSON 형태의 데이터를 요청할 수 있다.


레벨 2 – HTTP Method

레벨 1의 URL + HTTP Merhod 조합으로 리소스를 구분하는 것으로 응답 상태를 HTTP Status code 를 활용한다. 현재 가장 많은 Restful API가 이 단계를 제공한다.

GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1

Host: royalhope.nhs.uk

발생한 에러의 종류를 커뮤니케이션하기 위해 상태코드(status code)를 사용하는 것, 그리고 안전한 오퍼레이션(GET 등)과 안전하지 않은 오퍼레이션 간의 강한 분리를 제공하는 것이 레벨 2의 핵심 요소이다. 우선, Status Code를 사용한다는 것은 어떤 의미일까?기존에는 유저 생성 요청을 했을 경우 302 등의 리다이렉트 요청을 서버에서 내려주는 방식이었다면,지금은 201(created)로 유저 생성 성공을 알릴 뿐 페이지 이동은 Client 단에서 해결하는 방식이다.(login의 경우 성공은 200, 실패시 인증실패는 401, 성공했으나 권한 문제시엔 403 등)즉, 서버는 순수하게 api로서의 기능만을 제공하게 된다.(view는 Client에서..)

두번째로, 강한 분리를 제공하는 것이 어떤 이점이 있는 것일까?

HTTP에서 GET은 멱등방식으로 자원을 추출하는데, 이에 어떤 순서로든, 얼마든지 호출하든 매번 같은 결과를 얻도록 한다. 이에 통신상의 모든 참여자에게 ‘캐싱’기능을 지원하는 다양한 방법을 제공한다.


레벨 3 – 하이퍼미디어 컨트롤

HATEOAS(Hypertext As The Engine Of Application State) 애플리케이션 상태 엔진으로서의 하이퍼미디어 ㅡㅡ..

하이퍼미디어란 하나의 컨텐츠가 텍스트나 이미지, 사운드와 같은 다양한 포멧의 컨텐츠를 링크하는 개념이다. 이것은 관련 컨텐츠를 보기위해 링크를 따라가는 방식과 유사한 방식으로 동작하는데, 클라이언트가 다른 자원에 대한 링크를 통해 서버와 (잠재적으로 상태 변이를 초래하는) 상호작용을 한다.

즉, 특정 API를 요청한 후 다음 단계로 할 수 있는 작업을 알려주는 것이며, 다음 단계의 작업을 위한 리소스의 URI를 알려주는 것이다. 이 단계를 적용하면 클라이언트에 영향을 미치지 않으면서 서버를 변경하는 것이 가능하다.

GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1

Host: royalhope.nhs.uk
HTTP/1.1 200 OK
[various headers]
<openSlotList>

 <slot id = "1234" doctor = "mjones" start = "1400" end = "1450">
            <link rel = "/linkrels/slot/book"
            uri = "/slots/1234"/>
 </slot>
 <slot id = "5678" doctor = "mjones" start = "1600" end = "1650">
            <link rel = "/linkrels/slot/book"
            uri = "/slots/5678"/>
 </slot>
</openSlotList>

단점은, 클라이언트가 수행할 작업을 찾기 위해 링크를 따라기기 때문에 컨트롤 탐색에 꽤 많은 호출이 발생할 수 있다는 것이다. 또한 복잡성이 증가할 수 있으며, HTTP 요청상에 나타나는 부하로 낮은 지연시간이 요구될 때 문제가 될 수 있다. HTTP 기반의 REST 페이로드는 JSON 또는 바이너리 등의 포맷을 지원하므로 실제로 SOAP 보다 훨씬 간결할 수 있지만 쓰리프트와 같은 바이너리 프로토콜에는 상대가 되지 못한다. 또한 웹소켓의 경우 HTTP 초기 핸드셰이크 후에 클라이언트와 서버 간에 TCP 접속이 이루어지고 브라우저에서 스트림 데이터를 보낼 때 효율적일 수 있다. 따라서 HTTP가 대규모 트래픽에는 적합할 수 있지만 TCP 또는 다른 네트워킹 기술 기반의 프토토콜과 비교하면 낮은 지연시간이 필요한 통신에는 그다지 좋은 선택이 아닐 수 있다.

이러한 단점에도 HTTP 기반의 REST는 서비스 대 서비스의 상호작용을 위해 합리적이고 기본적인 선택이다.


RMM을 통한 REST 핵심 요소

1) resouce (레벨 1의 고민) : 애플리케이션에서 제공하는 resouce를 어떻게 분할하고 통합할 것인가?

2) http method, status code (레벨 2의 고민) : 에러 상황에 대한 적절한 처리와 method 도입을 통한 불필요한 다양성(복잡성) 제거

3) hypermedia (레벨 3의 고민) : API가 스스로 문서화 가능하도록 지원할 것인가?


RESTful API 설계

1. URI는 정보의 자원을 표현해야 한다.(리소스명은 동사보다는 명사를 사용)

2. 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE 등)으로 표현


URI 설계시 주의할 점

1. 슬래시 구분자(/)는 계층 관계를 나타내는데 사용

2. URI 마지막 문자로 슬래시(/)를 포함하지 않는다.

3. 하이픈(-)은 URI 가독성을 높이는데 사용

4. 밑줄(_)은 URI에 사용하지 않는다.

5. URI 경로에는 소문자가 적합하다.

6. 파일확장자는 URI에 포함하지 않는다.


Todo 기능을 구현한다고 가정했을 때의 Restful API 표준

 
endpoint 기능
GET /todos List all todos
POST /todos Create a new todo
GET /todos/:id Get a todo
PUT /todos/:id Update a todo
DELETE /todos/:id Delete a todo and its items
GET /todos/:id/items Get a todo item
PUT /todos/:id/items Update a todo item
DELETE /todos/:id/items Delete a todo item

(추가적으로) Spring Data Rest (흥미로운 부분이다. 학습 후 내용을 추가할 계획이다)

1. Richardson Maturity Model(RMM)의 레벨 3에 해당하는 hypermedia-driven HTTP resources를 제공하는 프레임워크

2. Spring Data Rest을 사용하지 않더라도 Spring Data Rest가 지원하는 HTTP method, Status Code, 기본 CRUD 자원,association resource, search resource, paging과 sorting에 따른 설계 방식을 학습하는 것도 좋은 설계 전략이다.


(추가적으로) 현재 통합 테스트도구로 postman을 사용중인데, 자동화된 테스팅 도구들을 좀 더 학습할 계획이다. 그리고 Backend의 경우 api만을 제공하나, 모바일은 특성상 다양한 버젼을 관리해야 하며, 웹은 최신기능을 업데이트 하지 않아도 사용하게 되어 코드 관리하기가 쉽다.(물론 웹도 글로벌 환경, CDN 배포 시간차 등을 고려하면 2가지 정도의 버전을 관리해야 한다.) 이 경우 REST를 지키면서 하는 DB 리팩토링은 매우 어렵다. 이 부분도 학습할 계획이다. (관련 책: 리팩토링 데이터베이스)

REST API란 무엇인가 #1 – 개념
Web Server

REST API란 무엇인가 #1 – 개념

REST API란 무엇인가 #1 – 개념

Click the link to see the article: 

조대협 님께서 블로그에 개제 해주신 내용을 보고 정리하였습니다. 

출처 : http://bcho.tistory.com/953

================================

● API의 본질은 무엇인가 -> Decoupling, 탈 동조화

● 그렇다면 Web API의 본질은 무엇인가 -> Decoupling + Platform Agnostic

※ Platform Agnostic 이란? 

   플랫폼에 종속적이 않음을 뜻한다. 즉, 특정 기기나 OS에서만 돌아가는 것이 아닌 광범위하게 사용될 수 있는 것.

   ex) 데이터 파일(텍스트파일, 그래픽 파일, 음원파일)은 윈도우든 OS X 든 안드로인드든 어디에서도 잘 돌아가니까.

● REST의 역사

웹(HTTP)의 창시자 중의 한사람인 Roy Fielding의 2000년 논문에서 소개.

” 현재 아키텍쳐가 웹의 본래 설계의 우수성을 많이 사용하지 못하고 있다고 판단했기 때문에, 

웹의 장점을 최대한 활용할 수 있는 네트워크 기반의 아키텍처를 소개한 것이 Representational state transfer(REST) 이다.

● REST의 기본

REST의 요소는 크게 리소스 // 메서드 // 메세지로 구성.

예로 “이름이 Terry인 사용자를 생성한다” 라는 호출이 있다면, “사용자”는 생성되는 리소스, “생성한다”라는 행위는 메서드

그리고 “이름이 Terry인 사용자”는 메시지가 된다.

이를 REST의 형태로 표현한다면, 

HTTP POST, http://myweb/users/

{

“users”:{

“name”:”terry”

}

}

 

와 같은 형태로 표현.

“생성한다”라는 행위의 의미를 갖는 메서드는 HTTP Post 메서드가 되고, 

생성하고자 하는 대상이 되는 “사용자” 라는 리소스는 http://myweb/users 라는 형태의 URI로 표현이 되며,

생성하고자 하는 사용자의 디테일한 내용은 JSON 문서를 이용해서 표현된다.

● HTTP 메서드

REST에서는 앞의 언급과 같이, 행위에 대한 메서드를 “HTTP 메서드” 그대로 사용한다.

HTTP 에는 여러가지 메서드가 있지만 REST에서는 CRUD(Create Read Update Delete)에 해당하는 4가지 메서드만 사용한다.

메서드  의미  Idempotent 
POST Create No
GET Select Yes
PUT Update Yes
DELETE Delete Yes

각각 POST, GET, PUT, DELETE는 각각의 CRUD 메서드에 대응된다. 

여기에 Idempotent라는 분류를 추가하였는데, Idempotent는 여러번 수행을 해도 결과가 같은 경우를 의미한다.

예를 들어 a++은 Idempotent 하지 않다고 하지만(호출시 마다 a값이 증가 되기 때문), 

a=4와 같은 명령은 반복적으로 수행해도 Idempotent하다고 한다.(a=4는 값이 고정된 명령이기 때문)

POST 메서드의 경우에는 리소스를 추가하는 연산이기 때문에 idempotent 하지 않지만 

나머지 GET, PUT, DELETE 메서드는 반복 수행해도 Idempotent 하다.

따라서 GET의 경우 게시물의 조회수 카운트를 늘려준다던가 하는 기능을 같이 수행했을 때는 

Idempotent 하지 않은 메서드로 정의해야 한다.

※ Idempotent의 개념을 설명한 이유는 REST는 각 개별 API를 상태 없이 수행하게 됩니다. 

   따라서 해당 REST API를 다른 API와 함께 호출하다가 실패하였을 경우, 트렌젝션 복구를 위해서 다시 실행해야 하는 경우가 있는데, 

   Idempotent 하지 않은 메서드들의 경우는 기존 상태를 저장 했다가 다시 복원해줘야하는 문제가 있지만, Idempotent한 메서드의 경우에는 

   반복적으로 다시 메서드를 수행해주면 됩니다.

   예를 들어 게시물 조회를 하는 API가 있을때, 조회시 마다 조회수를 올리는 연산을 수행한다면 이 메서드는 Idempotent 하다고 볼 수 없고, 

   조회하다가 실패하였을 때는 올라간 조회수를 다시 -1 만큼 빼줘야 합니다. 

   즉 Idempotent 하지 않은 메서드에 대해서는 트렌젝션에 대한 처리에 특히 주의가 필요합니다.

 

● REST의 리소스

REST는 리소스 지향 아키텍쳐 스타일이라는 정의 답게 모든 것을 리소스, 즉 명사로 표현을 하며 각 세부 리소스에는 ID를 붙인다.

사용자라는 리소스 타입을 http://myweb/users 라고 정의 했다면, terry라는 id를 갖는 리소스는

http://myweb/users/terry 라는 형태로 정의한다.

REST의 리소스가 명사의 형태를 띄우다 보니, 명령(Operation)성의 API를 정의하는 것에서 혼동이 올 수 있다.

예를 들어 “Push 메시지를 보낸다”는 보통 기존의 RPC(Remote Procedure Call)나 함수성 접근에서는 

/myweb/sendpush 형태로 잘못 정의가 될 수 있지만, 이러한 동사형을 명사형으로 바꿔서 적용해보면

리소스 형태로 표현하기가 조금 더 수월해 진다.

“Push 메시지 요청을 생성한다.”라는 형태로 정의를 변경하면, API 포맷은 POST/myweb/push 형태와 같이

명사형으로 정의가 될 수 있다. 

물론 모든 형태의 명령이 이런 형태로 정의가 가능한 것은 아니지만, 되도록이면 리소스 기반의 명사 형태로

정의를 하는게 REST 형태의 디자인이 된다.

☞ REST API의 간단한 예제

사용자 생성

다음은 http://myweb/users 라는 리소스를 이름은 terry, 주소는 seoul 이라는 내용(메시지)으로 HTTP POTS를 이용해서

생성하는 정의이다.

           HTTP POST, http://myweb/users/

          {

          “name”:”terry”
          “addreses”:”seoul”

          } 

– 조회 –
 
다음은 생성된 리소스중에서 http://myweb/users 라는 사용자 리소스 중에 id가 terry인 사용자 정보를 조회해오는 방식이다.
조회이기 때문에 HTTP GET을 사용한다.
 

           HTTP GET, http://myweb/users/terry
– 업데이트 –
 
다음은 http://myweb/users 라는 사용자 리소스중에, id가 terry인 사용자 정보에 대해서, 주소를 “suwon”으로 수정하는 방식이다.
수정은 HTTP PUT 메서드를 사용한다.
HTTP PUT, http://mtweb/users/terry
{
“name”:”terry”
“address”:”suwon”
}
 
– 삭제 –
 
마지막으로 http://myweb/user 라는 사용자 리소스 중에, id가 terry인 사용자 정보를 삭제하는 방법이다.
 

            HTTP DELETE, http://myweb/users/terry

            API의 정의를 보면 상당히 간단하다. 단순하게 리소스를 URI로 정해준 후에, 거기에 HTTP 메서드를 이용해서 

CRUD를 구현하고 메시지를 JSON으로 표현하여 HTTP Body에 실어 보내면 된다. POST URI에 리소스 id가 없다는
것을 빼면 크게 신경쓸 부분이 없다.
 
 
 

● REST의 특성

◎ 유니폼 인터페이스(Uniform Interface)

REST는 HTTP 표준에만 따른다면, 어떠한 기술이라던지 사용이 가능한 인터페이스 스타일이다. 

예를 들어 HTTP + JSON으로 REST API를 정의했다면, 안드로이드 플랫폼이건, IOS 플랫폼이건, 

또는 C나 Java / Python 이건 특정 언어나 기술에 종속 받지 않고 HTTP와 JSON을 사용할 수 있는

모든 플랫폼에 사용이 가능한 느슨한 결합(Loosely Coupling) 형태의 구조이다.

※ 흔히들 근래에 REST를 이야기하면, HTTP + JSON을 쉽게 떠올리는데, JSON은 하나의 옵션일뿐, 메시지 포맷을 

   꼭 JSON으로 적용해야할 필요는 없다. 자바스크립트가 유행하기전에만 해도 XML 형태를 많이 사용했으며, 근래에

   들어서 사용의 편리성 때문에 JSON을 많이 사용하고 있지만, XML을 사용할 경우, XPath, XSL 등 다양한 XML 프레임웍을

   사용할 수 있을뿐만 아니라 메시지 구조를 명시적으로 정의할 수 있는 XML Scheme나 DTD등을 사용할 수 있기 때문에,

   복잡도는 올라가더라도, 메시지 정의의 명확성을 더할 수 있다.

 

◎ 무상태성/스테이트리스(Stateless)

 
REST는 Representational State Transfer의 약어로 Stateless(상태를 유지하지 않음)이 특징 중의 하나이다.
 
상태가 있다, 없다의 의미는 사용자나 클라이언트의 컨택스트를 서버쪽에 유지 하지 않는다는 의미로,
쉽게 표현하면 HTTP Session과 같은 컨텍스트 저장소에 상태 정보를 저장하지 않는 형태를 의미한다.
 
상태 정보를 저장하지 않으면 각 API 서버는 들어오는 요청만을 들어오는 메시지로만 처리하면 되며, 
 
세션과 같은 컨텍스트 정보를 신경쓸 필요가 없기 떄문에 구현이 단순해 진다.
 
 

◎ 캐싱 가능(Cacheable)

REST의 큰 특징 중의 하나는 HTTP라는 기존의 웹 표준을 그대로 사용하기 때문에, 

웹에서 사용하는 기존의 인프라를 그대로 활용이 가능하다.

HTTP 프로토콜 기반의 로드 밸러서나 SSL은 물론이고, HTTP가 가진 가장 강력한 특징중에 하나인 

캐싱 기능을 적용할 수 있다. 일반적인 서비스 시스템에서 60%에서 많게는 80% 가량의 트랜잭션이 Select와 같은 

조회성 트랜잭션인 것을 감안하면, HTTP의 리소스들을 웹캐시 서버등에 캐싱하는 것은 

용량이나 성능 면에서 많은 장점을 가지고 올 수 있다. 구현은 HTTP 프로토콜 표준에서 사용하는

“Last-Modified” 태그나 E-Tag를 이용하면 캐싱을 구현할 수 있다.

아래와 같이 Client가 HTTP GET을 “Last-Modified” 값과 함께 보냈을 때, 컨텐츠가 변화가 없으면 REST 컴포넌트는

“304 Not Modified”를 리턴하면 Client는 자체 캐쉬에 저장된 값을 사용하게 된다.

그림 1. Last-Modified 필드를 이용한 캐싱 처리 방식

이렇게 캐시를 사용하게 되면 네트워크 응답시간 뿐만 아니라, REST 컴포넌트가 위치한 서버에 트랜잭션을 

발생시키지 않기 때문에, 전체 응답시간과 성능 그리고 서버의 자원 사용률을 비약적으로 향상시킬 수 있다.

◎ 자체 표현 구조(Self-descriptiveness)

REST의 가장 큰 특징 중의 하나는 REST API 자체가 매우 쉬워서 API 메시지 자체만 보고도 API를 이해할 수 있는 

Self-descriptiveness 구조를 갖는 다는 것이다. 리소스와 메서드를 이용해서 어떤 메서드에 무슨 행위를 하는지를 알 수 있으며,

또한 메시지 포맷 역시 JSON을 이용해서 직관적으로 이해가 가능한 구조이다.

대부분의 REST 기반의 OPEN API 들이 API 문서를 별도로 제공하고 있지만, 디자인 사상은 최소한의 문서의 도움만으로도 

API 자체를 이해할 수 있어야 한다.

◎ 클라이언트 서버 구조(Client-Server 구조)

근래에 들면서 재 정립되고 있는 특징 중의 하나는 REST가 클라이언트 서버 구조라는 것이다.

REST 서버는 API를 제공하고, 제공된 API를 이용해서 비즈니스 로직 처리 및 저장을 책임진다.

클라이언트의 경우 사용자 인증이나 컨택스트(세션, 로그인 정보)등을 직접 관리하고 책임 지는 구조로 역할이 나뉘어 지고 있다.

이렇게 역할이 각각 확실하게 구분되면서, 개발 관점에서 클라이언트와 서버에서 개발해야 할 내용들이 명확하게 되고 

서로의 개발에 있어서 의존성이 줄어들게 된다.

◎ 계층형 구조(Layered System)

계층형 아키텍쳐 구조 역시 근래에 들어서 주목받기 시작하는 구조인데, 클라이언트 입장에서는 REST API 서버만 호출한다.

그러나 서버는 다중 계층으로 구성될 수 있다. 순수 비즈니스 로직을 수행하는 API 서버와 그 앞단에 사용자 인증(Authentication),

암호화(SSL), 로드밸런싱 등을 하는 계층을 추가해서 구조상의 유연성을 둘 수 있는데, 

이는 근래에 들어서 앞에서 언급한 마이크로 서비스 아키텍쳐의 API Gateway나 간단한 기능의 경우에는 HA Proxy나

Apache와 같은 Reverse Proxy를 이용해서 구현하는 경우가 많다.

● REST 안티 패턴

REST 디자인시 하지 말아야 할 안티 패턴에 대한 내용이다.

◎ GET/POST를 이용한 터널링

가장 나쁜 디자인 중 하나가 GET이나 POST를 이용한 터널링이다.

http://myweb/users?method=update&id=terry 이 경우가 전형적인 GET을 이용한 터널링이다.

메서드의 실제 동작은 리소르르 업데이트 하는 내용인데, HTTP PUT을 사용하지 않고, 

GET에 쿼리 파라미터로 method=update라고 넘겨서, 이 메서드가 수정 메서드임을 명시했다.

대단히 안좋은 디자인인데, HTTP 메서드 사상을 따르지 않았기 때문에, REST라고 부를 수 도 없고,

또한 웹 캐시 인프라 등도 사용이 불가능하다.

또 많이 사용하는 안좋은 예는 POST를 이용한 터널링이다. Insert(Create)성 오퍼레이션이 아닌데도 불구하고,

JSON 바디에 오퍼레이션 명을 넘기는 형태인데 예를 들어 사용자 정보를 가지고 오는 API를 아래와 같이 

POST를 이용해서 만든 경우이다. 

HTTP POST, http://myweb/users/
{

“getuser”:{

“id”:”terry”,

}

}

◎ Self-descriptiveness 속성을 사용하지 않음

앞서 특징에서 설명한 바와 같이 REST의 특성 중 하나는 자기 서술성(Self-descriptiveness) 속성으로 REST URI와

메서드 그리고 쉽게 정의된 메시지 포맷에 의해서 쉽게 API를 이해할 수 있는 기능이 되어야 한다.

특히나 자기 서술성을 깨먹는 대표적인 사례가 위에서 언급한 GET이나 POST를 이용한 터널링을 이용한 구조가 된다.

 
 

◎ HTTP Response code를 사용하지 않음

다음으로 많이 하는 실수 중의 하나가 HTTP Response code를 충실하게 따르지 않고, 성공은 200, 실패는 500과 같이 

1~2개의 HTTP Response code만을 사용하는 경우이다. 심한 경우에는 에러도 HTTP Response code 200으로 정의한 후

별도의 에러 메시지를 200 response code와 함께 보내는 경우인데, 이는 REST 디자인 사상에도 어긋남은 물론이고

자기 서술성에도 어긋난다.

AngularJS 란 무엇인가?
angularJs

AngularJS 란 무엇인가?

AngularJS 란 무엇인가?

Click to the link to go to the site:

===============

AngularJS 개념

AngularJS 는 SPA(Single Page Application) 프레임워크라고 합니다.

예를 들어, 하나의 웹 페이지가 실행할 때 View 단에 해당되는 부분이 페이지의 주소가 바뀌지 않으면서 또 다른 새로운 view 를  동적으로 로드하여  사용하는 것을 SPA 라고 합니다.

이러한 SPA 를 편하게 사용하도록 도움을 주는 것이 AngularJS 와 같은 자바스크립트 프레임워크입니다.

그래서 AngularJS 는 SPA 를 만들때 도움을 주는 프레임워크이고 자바스크립트 기반의 MV* 오픈소스 프레임워크라고도 합니다.

결론적으로 SPA & 자바스크립트 기반의 MV* 프레임워크입니다.

MVC

그렇다면, MV* 패턴은 무엇인가?

자바스크립트 공부를 시작하면서 생소한 용어들 중에 디자인 패턴이란 용어가 있습니다.

디자인 패턴은 건축으로치면 공법에 해당하는 것으로 소프트웨어의 개발 방법을 공식화 한 것으로써, 소수의 뛰어난 엔지니어가 해결한 문제들에 대한 규칙들을 다수의 엔지니어들이 문제를 처리 할 수 있도록 한 규칙들이면서, 구현자들 간의 커뮤니케이션의 효율성을 높이는 기법을 디자인 패턴이라고 합니다.

MVC란 Model View Controller의 약자로 에플리케이션을 세가지의 역할로 구분한 개발 방법론입니다.

아래의 그림처럼 사용자가 Controller를 조작하면 Controller는 Model을 통해서 데이터를 가져오고 그 정보를 바탕으로 시각적인 표현을 담당하는 View를 제어해서 사용자에게 전달하게 됩니다.

위의 그림을 웹에 적용해 보자면…

1. 사용자가 웹사이트에 접속한다. (Uses)

2. Controller는 사용자가 요청한 웹페이지를 서비스 하기 위해서 모델을 호출한다. (Manipulates)

3. 모델은 데이터베이스나 파일과 같은 데이터 소스를 제어한 후에 그 결과를 리턴한다.

4 .Controller는 Model이 리턴한 결과를 View에 반영한다. (Updates)

5. 데이터가 반영된 VIew는 사용자에게 보여진다. (Sees)

 

Controller

사용자가 접근 한 URL에 따라서 사용자의 요청사항을 파악한 후에 그 요청에 맞는 데이터를 Model에 의뢰하고, 데이터를 View에 반영해서 사용자에게 알려준다. 

Model

일반적으로 CI의 모델은 데이터베이스 테이블에 대응된다. 이를테면 Topic이라는 테이블은 topic_model이라는 Model을 만든다. 그런데 이 관계가 강제적이지 않기 때문에 규칙을 일관성 있게 정의하는 것이 필요하다.

View

View는 클라이언트 측 기술인 html/css/javascript들을 모아둔 컨테이너이다. 

MV* (통칭으로 MVstar 라고 말합니다)

– MVC

Model

View

Controller

– MVVM (Model-View-ViewModel)

– MVP (Model View Presenter)

MVC 패턴의 프레임워크를 통칭적으로 MV스타(MV*) 프레임워크라고 합니다.

AngularJS 참고사이트

출처: http://webclub.tistory.com/206 [Web Club]

Angular Seed

 – 처음 시작을 위한 기본구조 제공

 – http://github.com/angualr/angular-seed 

 – http://ionicframework.com

AngularJS 구성요소

1. 지시자(Directive) 

– 뷰(View) 영역 

– 특정한 html 태그에 AngularJS 의 기능을 적용하고자 할 때 사용하는 것이 Directive 란 지시자를 사용하는데 AngularJS 의 Directive 는 ng 로 시작하는 지시자들이 많이 있습니다. 예) ng-*

2. 필터(Filters) 

– 어떤 데이터를 화면에 출력하는데 있어서 원하는 데이터만을 필터링하여 가져다 사용할 수 있도록 해주는 기능입니다.

3. 데이터 바인딩(Data Binding) 

– 표형태의 데이터들을 원하는 위치에 사용하기 편하게 바인딩하도록 해줍니다.

4. 컨트롤러(Controller) 

– 메인 컴포넌트 

– 기능별로 묶어서 사용하도록 해줍니다.

5. 서비스(Service) 

– 비즈니스 로직

AngularJS Expressions(표현식)

표현식 (Expressions)

– {{ }} 로 사용됨 (표현식 안에는 자바스크립트 문법을 사용할 수 있습니다)

– JavaScript 의 모든 문법을 지원하지 않음.

– 배열 등 선언 가능합니다.

사용 예

– {{ 표현식 }}

– {{ name }} 

– {{ 3 % 5 }} 의 결과값이 출력됩니다.

– {{ “안녕” + “하세요“ }} 문자열과 문자열을 접합한 결과가 나타납니다.

지시자(Directive)

새로운 형태의 HTML 태그/속성/속성값을 만들어서 정의해주는 것을 지시자라고 합니다.

다음의 ng-app=”” 과 같은 태그와 속성/속성값을 정의할 수 있습니다.

ex) <body ng-app=””>

위의 코드와 같이 html 이나 body 태그에 ng-app=”” 을 지시자를 명시해 줌으로써 AngularJS 를 사용할 준비 단계를 설정합니다.

ng-app 은 data-ng-app 으로 사용할 수 있는데 ng 앞에는 모두 data 가 생략되어 있습니다.

다시말해서, ng-app 은 모듈을 정의해 주는 것입니다.

출처: http://webclub.tistory.com/206 [Web Club]