openresty에서 lua를 이용한 health check url을 만들었다. 


nginx는 파일 기반으로 되어 있고 문법이 그다지 친절하지 않아서, openresty의 lua를 이용하면 좀 shared memory를 공유하는 기법이 있다. 전역 변수를 lua_shared_dict을 사용하면 모든 worker에서 서로 공유할 수 있어 편리한다.


공유 dict에 값이 없으면 200으로 처리해 서비스되도록 한다. 그리고 공유 메모리(lua_shared_dict)의 크기는 작게 한다. 



http {

    lua_shared_dict dicts    16k;

    

    ....

     server {

        server_name _;


        listen 80;

        root /...


        location / {

            return 404;

        }


        location ~* \.(?:ico|css|js|gif|jpe?g|png|gif|eot|ttf|ott|woff2?|swf|svg|zip)$ {

            expires 1y;

        }


        location /health_off {

            default_type text/html;

            content_by_lua_block {

                local d = ngx.shared.dicts

                d:set("health", 400)

                ngx.say("health-off")

             }

             allow       192.168.0.0/16;

             allow       172.16.0.0/12;

             allow       127.0.0.1;

             deny        all;

         }


        location /health_on {

            default_type text/html;

            content_by_lua_block {

                local d = ngx.shared.dicts

                d:set("health", 200)

                ngx.say("health-on")

            }

            allow       192.168.0.0/16;

            allow       172.16.0.0/12;

            allow       127.0.0.1;

            deny        all;

        }


        location /health_check.html {

            access_log  off;

            allow       all;


            default_type text/html;

            access_by_lua_block {

                local dogs = ngx.shared.dicts

                local status = tonumber(dogs:get("health")) or 200

                if status == 400 then

                        return ngx.exit(400)

                end

                return ngx.exit(200)

            }

        }

...

}




결과는 다음과 같다. 


$ curl -i http://localhost/health_check.html

200

$ curl -i http://localhost/health_off

$ curl -i http://localhost/health_check.html

400

$ curl -i http://localhost/health_on

$ curl -i http://localhost/health_check.html

200



**************


진짜 주의할 점은 ngx.exit 사용시 ngx.say를 함께 사용해서는 안된다. ngx.exit 앞에 ngx.say를 사용하면 exit 값이 나타나지 않고 200으로만 리턴한다. ngx.exit를 사용할 때는 ngx.say를 사용하지 않는다. 



Posted by '김용환'
,



1. 


한 라인 주석은 --

멀티 라인 주석은 --[[  코드  ]]--

동일(eual) ==

동일하지 않음(not equal) ~=

if문에 ()를 사용하지 않는다





2. 


lua블럭을 쓸 때는 비슷한 내용이 있다. 


content_by_lua_block {

}

 

content_by_lua '

';



general하게 쓸 때는 access_by_lua_block 또는 access_by_luay를 사용한다. 





3. nginx 의 변수를 lua내에서 사용 가능하다.


local page = ngx.var.arg_page

local authorization = ngx.var.http_authorization

local host = ngx.var.host





공부할 만한 자료 . 


Using ngx_lua / lua-nginx-module in pixiv from Shunsuke Michii


Posted by '김용환'
,


echo문을 사용해 yes/no와 같은 답을 얻어야 할 때가 있다.


echo "yes/no" 라고 실행하면 개행 문자가 들어가기 때문에 다음 라인에 yes 또는 no를 입력하게 된다.


이런 불편함을 없애기 위해 \c 이스케이프를 사용할 수 있다.


이스케이프를 쓰려면 유닉스 계열마다 다르게 동작하는 부분이 있다.


$ echo "(yes/no)?"

(yes/no)?

$ echo "(yes/no)?\c"

(yes/no)?\c


맥이나 센트OS에서는 -e를 매개변수로 사용하면 이스케이프 처리된다.


$ echo -e "(yes/no)?\c"

(yes/no)? $



이를 근거로 read 커맨드를 같이 활용하면 다음과 같이 사용가능하다.


$ echo -e "(yes/no)?\c" ; read answer ; echo "$answer"

(yes/no)?yes

yes



이스케이프 문자를 조사하니 다음과 같다.



문자

출력

\b

백스페이스

\c

새로운 라인을 종료하지 않는 라인

\f

폼피드

\n

새로운 라인

\r

캐리지 리턴

\t

탭 문자

\\

백슬래시 문자

\0nnn

해당 문자의 ascii 값은 nnn이고 nnn은 8진수로 1자리부터 3자리를 의미한다


'unix and linux' 카테고리의 다른 글

export -p  (0) 2017.01.31
프롬프팅(prompting) PS1, PS2  (0) 2017.01.31
echo 와 >& 팁  (0) 2017.01.19
네트워크 카드의 네트워크 트래픽 확인하기 - iftop  (0) 2017.01.19
sar를 대체할 수 있는 dstat  (0) 2017.01.19
Posted by '김용환'
,


카산드라는 복제본을 동기화 상태로 유지하기 위해 여러 메커니즘을 사용한다. 데이터 복구 작업은 일반적으로 세 가지 범주로 나뉜다.


* Synchronous read repair : 데이터를 읽으면서 여러 개의 복제본을 비교할 때, 카산드라는 다른 노드에 체크섬(checksum)을 요청한다. 체크섬이 일치하지 않으면 전체 복제본에 요청을 보내 로컬 버전과 비교한다. 최신 타임 스탬프의 데이터가 반환되고 모든 복제된에 해당 데이터를 복제되도록 전달된다. 요청을 받을 때 오래된 데이터가 복구된다.(일명 read repair라 불린다)


* Asynchronous read repair : 카산드라는 읽기 작업 중에 나머지 복제본도 복구할 수 있게 한다. 카산드라의 각 테이블에는 read_repair_chance (기본 값은 0.1, 즉 10%) 설정이 있다. 설정은 데이터를 읽을 때 비교되지 않는 복제본을 얼마나 처리할지를 결정한다. 


consistency level이 one이면 비교할 대상이 없기 때문에 read repair가 발생되지 않는다. 그리고 quorum이면 모든 노드가 아니라 질의를 받은 노드만 복구된다.


* nodetool repair 직접 수행 : 전체적으로 복구를 수행한다. 최소한 테이블 스키마에 설정된 gc_grace_seconds(기본 10일)안에 한 번 실행해야 하지만, 운영 노하우가 필요하다. 


카산드라의 모든 수정(변경 내용)은 immutable인데 반해 delete는 클라이언트에 주지 말라는 마커(tombstone)만 있다. 따라서 compaction이 호출될 때에만 실제 삭제된다. 그리고 gc가 발생한다.





<운영 노하우>


데이터 consistency가 낮아 있는 cassandra에 node repair를 하다가 gc가 늘어나 서버가 hang이 되지 않도록 운영 작업을 고민했다.


cassandra에 read/write를 모두 quorum(java driver에서 consistency level의 기본값은 one이다)으로 바꿔 consistency를 높였고(이전에는 되어 있지 않았다) 자연스럽게 read operation 시 asynchronous read repair가 발생되도록 해놨다.


기본 consistency level를 결정한다. 


     QueryOptions queryOptions = new QueryOptions();

queryOptions.setFetchSize(QueryOptions.DEFAULT_FETCH_SIZE);

queryOptions.setConsistencyLevel(ConsistencyLevel.QUORUM);


private Cluster cluster;

..

cluster = Cluster.builder().addContactPoints(contactPoints).

withQueryOptions(queryOptions).

withPoolingOptions(poolingOptions).

withSocketOptions(socketOptions).build();





테이블의 성격에 따라 consistency level을 정할 수 있다. 이것은 테이블의 성격이 가장 우선시 된다. 테이블 성능과 cql 쿼리, compaction간의 고민이 필요하다. 


Statement statement = QueryBuilder.select().from(CASSANDRA_KEY_SPACE, CASSANDRA_TABLE_ACTIVITY_ACTION_COUNT)

.where(QueryBuilder.eq("profile_id", actorId)).and(QueryBuilder.eq("guid", id))

.setConsistencyLevel(ConsistencyLevel.ONE);





특정 테이블에서는 consisteny level을 quorum으로 했더니 timeout이 발생했다.


데이터가 크고 secondary index도 쓰고.. timeout이 발생하기 때문에 consisteny level을 one으로 수정했다(성능 이슈)


 com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed



테이블의 성격에 따라 다르게 node repair를 실행하는 것이 좋다.  



Posted by '김용환'
,

openresty 1.11.2 설치

nginx 2017. 1. 19. 19:03


openresty 를 설치할 때 centos 하위 버전에서는 설치가 안될 수 있으니. requirement를 살펴보면 좋을 듯 하다.

예를 들어 luajit을 사용할 수 있도록 PATH에 넣어달라는 문구를 받을 수 있다.



$ ./configure -j2 --with-pcre=/home/www/pcre-8.39

platform: linux (linux)

you need to have ldconfig in your PATH env when enabling luajit.


https://openresty.org/en/installation.html

You should have perl 5.6.1+libreadlinelibpcrelibssl installed into your system. For Linux, you should also ensure that ldconfig is in your PATH environment.


$ ls  /sbin/ldconfig

/sbin/ldconfig


$ vi ~/.bashrc

export PATH=$PATH:/sbin


$ source ~/.bashrc






http://openresty.org/en/getting-started.html에 따라 필수 유틸리티와 openresty를 설치한다.




./configure --prefix=/usr/local/nginx  --with-pcre=/usr/local/src/pcre-8.39





$ sudo yum clean all

$ sudo yum -q -y install pcre-devel.x86_64 curl-devel boost-devel readline-devel pcre-devel openssl-devel gcc

$ cd /home/www

$ wget http://story-ftp.daumkakao.io/ftp/archives/install/binaries/pcre-8.39.tar.gz

$ tar -xvf pcre-8.39.tar.gz

$ wget http://story-ftp.daumkakao.io/ftp/archives/install/binaries/openresty-1.11.2.1.tar.gz

$ tar -xvf openresty-1.11.2.1.tar.gz

$ cd /home/www/openresty-1.11.2.1 

$ ./configure -j2 --with-pcre=/home/www/pcre-8.39  --prefix=/usr/local/nginx --with-http_v2_module --with-http_stub_status_module

$ make -j2

$ sudo make install




(하위 centos버전에서는 gmake, gmake install을 추가로 실행할 수 있다)





openresty를 처음 설치한 후 빈 디렉토리를 생성한다.


$ mkdir -p /usr/local/nginx/conf




로그는 /usr/local/nginx/nginx/log에 생기니 logs 디렉토리를 /usr/local/nginx/logs로 심볼링 링크를 건다. 


$ sudo ln -sf /usr/local/nginx/nginx/logs /usr/local/nginx/logs




/usr/local/nginx/conf/nginx.conf에 설정을 추가한다. 


worker_processes 10;
error_log logs/error.log;

events {
use epoll;
multi_accept on;
worker_connections 10240;
}

http {
server {
listen 8080;
location / {
default_type text/html;
content_by_lua '
ngx.say("<p>hello, world</p>")
';
}
location /health_check.html {
access_log off;
allow all;

default_type text/html;
return 200 "OK";
}
location ~ /nginx_status {
access_log off;
allow 192.168.0.0/16;
allow 172.16.0.0/12;
allow 127.0.0.1;
deny all;
}
}
}




다음과 실행한다. 


/usr/local/nginx/bin/openresty -c /usr/local/nginx/conf/nginx.conf

/usr/local/nginx/bin/openresty -s reload -c /usr/local/nginx/conf/nginx.conf




curl http://localhost/ 를 실행해 정상적으로 동작하는지 확인한다. 




openresty를 사용하는 이유는 nginx의 이상한 문법 구조를 lua로 우아하게 표현하고 싶어서이다..




Posted by '김용환'
,

echo 와 >& 팁

unix and linux 2017. 1. 19. 18:44



echo 와 >& 관련 내용 


<테스트 코드>

$ for i in "once"

  do

    echo "test"

     echo "Error" 1>&2

 done > /dev/null


<결과>

Error message



기본적으로 echo는 echo 출력을 표준 출력(파일 디스크립터(file descriptor) 1)으로 보내는 반면, 파일 설명자 2는 표준 에러이고 기본적으로 파일 리디렉션이나 파이프로 리디렉션되지 않는다. 


따라서 1>&2 표기법은 echo의 "Error" 메시지가 표준 에러로 리디렉션되야 한다는 것을 의미한다. 


Posted by '김용환'
,


트래픽이 어느 ip와 가장 많이 발생하는지 확인할 수 있다.


설치

$ sudo yum install iftop



실행

$ sudo iftop -i eth0





'unix and linux' 카테고리의 다른 글

echo 이스케이프 - \c  (0) 2017.01.23
echo 와 >& 팁  (0) 2017.01.19
sar를 대체할 수 있는 dstat  (0) 2017.01.19
sar 결과에 시간 안나오는 문제  (0) 2017.01.19
[shell] 널 커맨드(null command)  (0) 2017.01.16
Posted by '김용환'
,


시스템 모니터링 툴이 상당히 많지만, 그 중에 sar를 가장 좋아했다.


dstat은 터미널에서 색깔(ansi color)를 입혀 모니터링할 수 있다. sar가 할 수 있는 대부분의 모니터링을 쉽게 할 수 있다. (run queue 모니터링은 dstat에서는 아직 안되는 것 같다.)



과거의 dstat은 옵션이 많았는데, 최신 버전의 dstat은  깔끔하게 사용할 수 있다.



$ dstat -c -d -g -i -l -m -n -p -r -s -t -y





$ dstat -h

Usage: dstat [-afv] [options..] [delay [count]]

Versatile tool for generating system resource statistics


Dstat options:

  -c, --cpu              enable cpu stats

     -C 0,3,total           include cpu0, cpu3 and total

  -d, --disk             enable disk stats

     -D total,hda           include hda and total

  -g, --page             enable page stats

  -i, --int              enable interrupt stats

     -I 5,eth2              include int5 and interrupt used by eth2

  -l, --load             enable load stats

  -m, --mem              enable memory stats

  -n, --net              enable network stats

     -N eth1,total          include eth1 and total

  -p, --proc             enable process stats

  -r, --io               enable io stats (I/O requests completed)

  -s, --swap             enable swap stats

     -S swap1,total         include swap1 and total

  -t, --time             enable time/date output

  -T, --epoch            enable time counter (seconds since epoch)

  -y, --sys              enable system stats


  --aio                  enable aio stats

  --fs, --filesystem     enable fs stats

  --ipc                  enable ipc stats

  --lock                 enable lock stats

  --raw                  enable raw stats

  --socket               enable socket stats

  --tcp                  enable tcp stats

  --udp                  enable udp stats

  --unix                 enable unix stats

  --vm                   enable vm stats


  --plugin-name          enable plugins by plugin name (see manual)

  --list                 list all available plugins


  -a, --all              equals -cdngy (default)

  -f, --full             automatically expand -C, -D, -I, -N and -S lists

  -v, --vmstat           equals -pmgdsc -D total


  --bw, --blackonwhite   change colors for white background terminal

  --float                force float values on screen

  --integer              force integer values on screen

  --nocolor              disable colors (implies --noupdate)

  --noheaders            disable repetitive headers

  --noupdate             disable intermediate updates

  --output file          write CSV output to file


delay is the delay in seconds between each update (default: 1)

count is the number of updates to display before exiting (default: unlimited)



Posted by '김용환'
,

로케일이 깨져서 발생한다.

LC_ALL 또는 LC_TIME의 값을 아무거나 넣고 sar를 실행한다. 

아니면 .bashrc에 export해서 로케일 정보를 저장토록 한다. 

 

$ LC_ALL=x sar  -r -f /var/log/sa/sa03


$ LC_TIME=1 sar  -r -f /var/log/sa/sa03



Posted by '김용환'
,



https://earth.nullschool.net/#current/chem/surface/level/overlay=cosc/orthographic=-235.92,28.73,765/loc=126.718,37.315










Posted by '김용환'
,