네트워크 담당자와 사전 협의를 통해 시스템 구성도 및 방화벽 구성(내/외부 IP) 등을 사전 협의해야 합니다. 네트워크가 폐쇄망인 경우 설치 SW (erlang, rabbitmq, mariadb, opendjk1.8 or java1.8등)의 yum 의존성을 체크하여 해당 라이브러리를 모두 다운로드 받아서 사전 배포되어야 합니다.
WorkCenter_app.yml 설정시 IP 주소는 내부IP 를 기입해야 하며, webUrl은 대표IP (L4스위치의 IP)주소로 설정합니다. WorkCenter-app.yml 파일의 Server: url 에는 대표IP 주소로 설정합니다.
YML 설정 파일 내의 IP address 는 localhost 대신 IP address 를 입력하는 것을 권장합니다. 간혹 공인IP와 사설IP간 변환시 NAT(Network Address Translation) 설정에 따라 서버에 접속을 못하는 경우가 발생할 수 있습니다.
네트워크 설정에서 방화벽 해제(open) 포트를 확인합니다.
구 분 | 구성 방식 | 용 도 | 포 트 |
---|---|---|---|
WorkCenter APP 서버 | Active-Active (round-robin방식) | WorkCenter Business Logic 및 API 제공 | 8080 |
In-Memory Grid 서버 | Active-Active (round-robin방식) | WorkCenter API 서버 내부에서 동작됨 데이터(in-memory) 공유를 위한 hazelcast 클러스터링 | 5701 |
TCP/IP (Netty) 서버 | Active-Standby (Sticky방식) | WorkCenter API 서버 내부에서 동작됨 Mini/Studio 와 TCP/IP 기반 Socket 통신 | 8081 |
Message Queue 서버 | Active-Active (round-robin방식) | 프로세스 스크립트 수행시 송수신 데이터 보장을 위한 메시지 큐 서버 (RabbitMQ) 4369 port : epmd, a helper discovery daemon 5671, 5672 : AMQP 15672 : HTTP API clients, management UI | 4369 (epmd) 5672(AMQP), 15672(HTTP) |
Database 서버 | Active-Standby (Sticky방식) | WorkCenter 관리/모니터링을 위한 데이터 저장 서버(MariaDB) | 3306 |
WorkCenter Admin 서버 | 단독 | WorkCenter 서버가 여러 개 실행되어 있는 경우 상태 모니터링을 위한 부가 서비스 | 8090 |
네트워크 담당자에게 요청하여 네트워크/L4 스위치 방화벽 Port 설정을 확인합니다.
네트워크/L4 스위치 방화벽 외부는 8080, 8081, 15672, 8090(optional) 포트를 해제하고, 방화벽 내부는 5672, 4369, 5671~3, 5701(Socket), 외부포트를 포함해서 해제합니다.
시스템 내에 설정된 방화벽 포트를 확인합니다. firewalld 는 최신 리눅스에서 기본으로 구성되는 방화벽 소프트웨어 입니다. Firewall daemon가 설치되어 있다면 iptables 가 비활성화 되어 있을 수 있습니다.
Root 계정으로 4.2절에서는 MariaDB설치는 이중화를 고려하지 않은 경우입니다. HA솔루션이 적용되어 있다면, 본 절에 명시된 Galera Cluster 패키지 설치는 생략합니다. 단, HA솔루션이 없는 경우는 고가용성 보장을 위해 MariaDB 전용 Galera Cluster를 설치, 3대의 서버에 구성해야 합니다.
Galera Cluster는 오픈소스로서 동기방식의 복제를 지원하며, 노드간 통신을 위해 wsrep(Write Set REPlication) API를 사용합니다. InnoDB만 지원하며 MySQL 5.5이상 및 MariaDB 10.4 이상 버전에서 사용 가능합니다.
Galera Cluster 3-Node(Active-Active-Active)로 모든 Node에서 트랜잭션이 발생하며 모든 Node에 트랜잭션 변경 데이터가 복제가 완료되어야 되는 실시간 동기화 방식입니다. 모든 Node에 데이터를 저장하기 전에 확인을 해야 하므로 LOCK문제와 Slow-Query 이슈를 피할 수 없습니다. Active-Active 로 구성할 경우 DB deadlock 발생이 빈번하여 Active-Active방식이 아닌 Active-Standby 구성을 권장합니다.
3개 이상의 서버를 구성되며, Master 가 될 서버를 Donor 라고 하고 나머지 서버들을 Joiner 라고 합니다. HA를 구성할 각각의 서버에 MariaDB Galera Cluster를 설치합니다. 4.2 MariaDB 설치를 참고하여 MariaDB 레파지토리가 추가되었는지 확인한 후 아래와 같이 Root 계정으로 galera cluster 를 설치합니다.
# yum install –y mariadb-server mariadb-client galera rsync
Galera Cluster 의 경우 짝수개의 서버로 구성되어 있으면 split-brain으로 인해 query가 실행되지 않습니다. 따라서, 반드시 홀수의 노드로 구성해야 하는데, 홀수 노드 구성이 어려운 경우Galera Arbitrator (https://galeracluster.com/library/documentation/arbitrator.html) 를 설치하여 quorum 개수를 홀수로 설정할 수 있습니다. MariaDB가 설치되어 있지 않은 가상의 다른 서버에 설치하여 garb파일을 열어 MariaDB Master-Slave 서버 노드 정보를 설정해야 합니다.
Galera Cluster 에서 사용하는 포트는 아래와 같이 4개 포트를 사용합니다.
클러스터에서 개별 노드로 데이터를 복제하여 노드를 클러스터와 동기화하는 프로세스를 프로비저닝이라고 하며 두가지(SST, IST) 방법을 제공합니다.
구 분 | 용 도 | 포 트 |
---|---|---|
SST (State Snapshot Transfer) | 새노드가 클러스터에 참여하면 SST를 실행해 다른 노드와 동기화합니다. | 4444 |
IST (Incremental State Transfer) | 기준 노드와 비교할 때 누락된 트랜잭션이 존재하면 동기화합니다. | 4568 |
Galera Cluster | 각 노드의 연동상태를 체크하고 멀티캐스트 복제시 이 포트에서 UDP전송과 TCP를 모두 사용 | 4567 |
MariaDB | MariaDB 클라이언트 연결 및 상태 스냅샷 전송 | 3306 |
방화벽 포트 허용을 위해 아래와 같이 명령어를 입력합니다.
# firewall-cmd --state (방화벽이 실행되지 않았을 경우 systemctl start firewalld 입력)
Running
# firewall-cmd --permanent --add-service=mysql
success
# firewall-cmd --permanent --add-port={4567,4568,4444}/tcp
success
# firewall-cmd --reload
success
# firewall-cmd --list-all
MariaDB 설정 파일 my.cnf파일을 확인합니다. MariaDB 를 위한 디렉토리 구조는 아래와 같습니다.
{mariadb_home}/data, /log, /log-bin, /plugins, /tmp, /undo 등 하위디렉토리가 있습니다.
Root 계정으로 설치하였으므로 {mariadb_home} 경로에서 owner와 group 을 변경합니다.
# chown –R mysql:mysql \*
4.2 MariaDB 설치를 참조하여 MariaDB 설정, User 및 DB생성에서 root 패스워드 설정까지 완료합니다.
세 개의 서버에 mariadb 서비스 상태를 확인 한 후 stop 시킵니다.
$ systemctl start mariadb // mariadb 서비스 시작
$ systemctl enable mariadb // mariadb 서비스 등록
$ systemctl status mariadb // mariadb 서비스 상태
$ systemctl stop mariadb // mariadb 서비스 중지
Master 가 될 master 서버를 정한 후 My.cnf파일에 아래와 같이 추가합니다.
// my.cnf 파일 위치 찾기
$ mysqld --verbose --help | grep -A 1 'Default options'
/etc/my.cnf
$vi /etc/my.cnf
[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera-4/libgalera_smm.so # libgalera_snm.so 모듈 위치
wsrep_cluster_address="gcomm://{mariadb_myserver_ip},{mariadb_joinerserver_ip} “ # 동기화할 서버 IP 목록
wsrep_cluster_name=aworks_cluster # cluster 명령을 입력, 모든 노드가 동일해야 함
wsrep_node_address="{mariadb_myserver_ip}“ # 현재 서버 IP
wsrep_node_name="{mariadb_myserver_hostname} “ # 현재 서버의 호스트명
wsrep_sst_method=rsync # 동기화 될 데이터 전송방식
wsrep_sst_auth=“user:password“ # 동기화 될 데이터 전송시에 사용할 MariaDB 계정
binlog_format=row # 바이너리 로그파일 형식
default_storage_engine=InnoDB # 스토리지 엔진 타입
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0 # 모든 IP에서 접근 허용
// my.cnf 파일 위치 찾기
$ mysqld --verbose --help | grep -A 1 'Default options'
/etc/my.cnf
$vi /etc/my.cnf
[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera-4/libgalera_smm.so # libgalera_snm.so 모듈 위치
wsrep_cluster_address="gcomm://{mariadb_master_server_ip},{mariadb_slave_server_ip} “ # 동기화할 서버 >IP 목록
wsrep_cluster_name=aworks_cluster # cluster 명을 입력, 모든 노드가 동일해야 함
wsrep_node_address="{mariadb_myserver_ip}“ # 현재 서버 IP
wsrep_node_name="{mariadb_myserver_hostname} “ # 현재 서버의 호스트명
wsrep_sst_method=rsync # 동기화 될 데이터 전송방식
wsrep_sst_auth=“user:password“ # 동기화 될 데이터 전송시에 사용할 MariaDB 계정
binlog_format=row # 바이너리 로그파일 형식
default_storage_engine=InnoDB # 스토리지 엔진 타입
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0 # 모든 IP에서 접근 허용
$ galera_new_cluster
$ systemctl start mariadb
$ systemctl status mariadb
mariadb.service - MariaDB 10.4.13 database server
Active: active (running) since 목 2020-07-09 14:12:48 KST; 2 months 7 days ago
7월 09 14:12:45 workcenter-cluster-2 rsyncd[525]: rsyncd version 3.1.2 starting, listening on port 4444
7월 09 14:12:45 workcenter-cluster-2 rsyncd[546]: connect from workcenter-cluster-1
7월 09 14:12:45 workcenter -cluster-2 rsyncd[546]: rsync to rsync_sst/ from workcenter-cluster-1
7월 09 14:12:45 workcenter -cluster-2 rsyncd[546]: receiving file list
7월 09 14:12:48 workcenter -cluster-2 systemd[1]: Started MariaDB 10.4.13 database server.
Master 와 Slave 서버가 정상적으로 동기화 되었는지를 확인하기 위해서 DBMS에 접속한 후 cluster 설정 값들을 확인합니다.
$ mysql –u root –p
Password:
MariaDB> show status like ‘wsrep_cluster_size’; // cluster size value = 2
MariaDB> show variables like ‘wsrep_cluster_address’; // cluster 에 참여한 노드 IP 2개 확인
MariaDB> show status like ‘wsrep_cluster_status’; // primary 로 설정
MariaDB> show status like ‘wsrep_%’ // Galera Cluster 모든 변수값 확인
JDBC 드라이브 연결시 Failover and load balancing modes 는 4가지로 구분됩니다.
Mode | Description |
---|---|
Sequential | MariaDB Galera Cluster 와 같은 multi-master 환경에서 연결 fail-over를 지원함. 이 모드는 slave에 대한 로드밸런싱 읽기를 지원하지 않는다. 커넥터는 연결 url에서 선언된 순서대로 호스트에 연결을 시도하므로 사용 가능한 첫번째 호스트가 모든 쿼리에 사용됨. MariaDB Connector/J 1.3.0 이상 (예시)jdbc:mariadb:sequential:host1,host2,host3/testdb |
Loadbalance | MariaDB Galera Cluster 와 같은 multi-master 환경에서 로드밸러싱 연결을 허용함. 이 모드는 slave에 대한 로드밸런싱 읽기를 지원하지 않음. 커넥터는 각 연결의 url에서 호스트를 무작위로 선택하여 모든 쿼리에 대한 로드밸런싱을 수행하므로 모든 호스트에 임의로 분산되는 연결의 결과로 쿼리가 로드밸런싱 됨. MariaDB Connector/J 1.2.0 이상 DB deadlock 발생 주의 필요 |
Replication | MariaDB replication cluster 와 같은 Master-Slave 환경에서 연결 failover 를 지원하는 모드임. 이 모드는 Read를 실행하기 전에 read-only로 설정된 경우 slave instance에 대한 로드밸러싱 읽기를 지원함. 커넥터는 연결에 대한 읽기 쿼리를 실행할 slave instance를 무작위로 선택하여 로드밸런싱 수행됨. MariaDB Connector/J 1.2.0 이상 |
aurora | Amazon Aurora cluster환경에서 failover 지원하는 모드임. 이 모드는 Read를 실행하기 전에 read-only 로 설정된 경우 slave instance 에 대한 로드밸런싱 읽기를 지원함. 커넥터는 연결에 대한 읽기 쿼리를 실행할 slave instance를 무작위로 선택하여 로드밸런싱 수행됨. MariaDB Connector/J 1.2.0 이상 |
Workcenter-app.yml 의 datasource 설정에서 sequential 모드로 변경합니다.
Spring:
datasource: // MariaDB Server-Client JDBC 연결
url:
jdbc:mariadb:sequential://master-server-ip:3306,slave-server-ip:3306/dbname?autoReconnect=true
username: root
password:
서로 다른 2개의 노드로 구성된 rabbitmq 의 클러스터 설정을 위해 먼저 Erlang 쿠키를 동일하게 설정합니다. 먼저 첫번째 노드의 쿠키 데이터를 확인합니다.
$> cd ~rabbitmq 또는 $>cd /var/lib/rabbitmq
$> ls -la
합계 24
drwxr-xr-x 5 rabbitmq rabbitmq 4096 7월 3 08:37 .
drwxr-xr-x. 69 root root 4096 10월 18 2019 ..
-r-------- 1 rabbitmq rabbitmq 21 9월 26 2019 .erlang.cookie
drwxr-x--- 2 rabbitmq rabbitmq 4096 9월 26 2019 config
drwxr-x--- 4 rabbitmq rabbitmq 4096 7월 24 13:29 mnesia
drwxr-x--- 2 rabbitmq rabbitmq 4096 9월 26 2019 schema
$> cat .erlang.cookie
CZDVBEVOWAEULTJOMCGJ
그리고 첫번째 노드에서 생성된 쿠키 데이터를 두번째 노드에도 동일하게 설정하기 위해 두번째 노드에서 다음과 같이 설정합니다. 읽기 전용 파일이므로 vim 에디터에서 wq!로 저장합니다.
$> cd \~rabbitmq
또는
$>cd /var/lib/rabbitmq
$>vi .erlang.cookie
CZDVBEVOWAEULTJOMCGJ
$> rabbitmqctl cluster_status
Cluster status of node rabbit@workcenter-cluster-2 ...
[{nodes,[{disc,['rabbit@workcenter-cluster-1',
'rabbit@workcenter-cluster-2']}]},
{running_nodes,['rabbit@workcenter-cluster-1','rabbit@workcenter-cluster-2']},
{cluster_name,<<"rabbit@workcenter-cluster-1">>},
{partitions,[]},
{alarms,[{'rabbit@workcenter-cluster-1',[]},
{'rabbit@workcenter-cluster-2',[]}]}]
$> rabbitmqctl stop_app
Stopping rabbit application on node rabbit@workcenter-cluster-2 ...
$> rabbitmqctl join_cluster --disc rabbit@workcenter-cluster-1
Clustering node rabbit@blockchain-cluster-2 with rabbit@workcenter-cluster-1
정지했던 2번 서버의 관리 애플리케이션을 다시 시작합니다.
$> rabbitmqctl start_app
Clust Starting node rabbit@workcenter-cluster-2 ...
completed with 3 plugins.
※ RabbitMQ 클러스터가 다수로 구성되는 경우 위의 2번 서버 설정처럼 추가되는 노드들에 대해 동일하게 작업합니다.
1번 서버와 2번 서버의 rabbitmq 클러스터 설정을 확인합니다.
$> rabbitmqctl cluster_status
2번 서버에서 1번 서버로 연결하였으므로 클러스터명은 1번 서버의 노드명이 사용됩니다.
running_nodes 에는 1번 노드와 2번 노드가 모두 명시됩니다.
RabbitMQ 의 경우 hostname을 통해 클러스터링 서버를 lookup 하기 때문에 hosts 파일에 등록되어야 합니다. Hostname 으로 클러스터링 대상 서버의 연결 여부를 확인합니다.
$ping <연결대상MQ서버의 HostName>
$ping workcenter1-svr 요청 시간이 만료되었습니다.
ping test 실패시 /etc/hosts 파일에 자기자신을 포함한 상대 클러스터링 서버의 IP 와 HostName을 등록되어 있는지 합니다.
$vi /etc/hosts
xxx.xxx.xxx.xxx workcenter1-svr
yyy.yyy.yyy.yyy workcenter2-svr
[root@workcenter-cluster-1:~] ls -la /etc/hosts
-rw-r--r-- 1 root root 232 9월 26 2019 /etc/hosts
[root@workcenter-cluster-1:~] cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.41.125 workcenter-cluster-1
192.168.41.127 workcenter-cluster-2
RabbitMQ 콘솔 화면에서 두 개의 노드가 연결되었는지 각각의 IP 로 접속합니다.
http://<rabbitmq_node1_ip>:15672/ 후 Login 한 후 Overviews 의 Nodes 에 두개의 노드가 클러스터 구성되었는지 확인합니다.
1번 또는 2번 서버의 콘솔 화면에서 큐를 생성 후 메시지를 publish 했을 때 다른 서버에서 정상적으로 조회가능한지 테스트합니다. 또한 한 개의 노드에서 큐 생성 후 메시지를 publish 한 후 다른 노드의 콘솔 화면에서 큐를 확인합니다.
미러링은 RabbitMQ 클러스터의 모든 노드의 데이터를 복제하여 특정 노드가 동작을 멈춘 경우 나머지 노드들에 의해 정상적으로 서비스가 가능하게 하도록 합니다.
RabbitMQ 의 미러링 설정은 웹콘솔 화면에서도 동일하게 수행할 수 있습니다.
$ rabbitmqctl set_policy ha-all ^aworks\. '{"ha-mode":"all", "ha-sync-mode":"automatic"}'
$ rabbitmqctl set_policy -n master -p develop ha-all "^.*\.ha.*" '{"ha-mode":"all"}'
$ rabbitmqctl set_policy ha-all “^.*\” '{"ha-mode":"all"}'.
2번 서버에서 큐를 생성하고 2번 서버를 shutdown 한 후 1번 서버에서도 2번 서버에서 생성한 큐가 조회 가능한지 테스트합니다.
2번 서버에서 Queues 탭에서 Add a new queue 를 선택 후 “test” 큐를 생성합니다.
리눅스 명령어로 $systemctl stop rabbitmq-server 명령어로 2번 서버 shutdown 합니다.
1번 서버에 웹 콘솔에 접속합니다.
1번 서버에서 2번 서버를 통해 생성한 큐 (“test”) 가 나타나는지 확인합니다.
cluster 설정에는 WorkCenter서버 2대의 내부IP 를 입력하고 domain 에 webUrl 에는 대표IP를 입력합니다.
spring:
datasource:
url: jdbc:mariadb:sequential://192.168.193.103:3306,192.168.193.104:3306/rpa2db?autoReconnect= true
username:
password:
hikari:
connection-timeout: 5000
rabbitmq:
username: mquser
password: 1234qwer
addresses: {workcenter_#1_내부IP}:5672, {workcenter_#2_내부IP}:5672
workcenter:
cluster:
enable: true
members:
- {workcenter_#1_내부IP}
- {workcenter_#2_내부IP}
domain:
name: aworks.com
description: This is the default domain
supervisor: super@aworks.com
webUrl: http://{workcenter_대표IP}:app_bind_port
swagger:
title: A.Works WorkCenter APP
description: Cloud RPA A.Works WorkCenter APP
basePackage: com.aworks.workcenter.service
license:
licenseUrl:
termsOfServiceUrl:
tokenUrl: http://{workcenter_대표IP}:app_bind_port/oauth/token