참고
프로젝트 소개
NOTE
반도체 설비에서 실시간으로 다양한 데이터가 생성되고 있으며, 설비 상태를 실시간으로 모니터링하기 위한: 시스템을 구축한다.
썸네일 이미지
최종 서버 아키텍쳐
•
기업연계 체험형 프로젝트 (삼성 semes)
•
참가인원 : 5명
•
역할 : BackEnd & Devops
◦
아래에 제가 담당한 영역은 기호로 표시가 되어있습니다.
프로젝트 목표
NOTE
•
설비 데이터를 취득할 수 있는 서버 구현
•
설비와 서버 간 데이터 송/수신을 위한 Client/Server 구현
•
서버에서 취합된 데이터를 표현하기 위한 UI 구현
프로젝트 진행
프로젝트 기획 & 설계(1주차)
NOTE
기업의 요구사항을 바탕으로, 구체적인 구현방식을 설계한다.
명세서
요구사항
•
데이터 명세서에 따른 데이터를 생성하며, 생성방식이나 가공방식은 자유롭게 진행한다.
◦
실제 데이터는 보안상의 이유로 받지못하므로, 각 데이터의 연관관계나 중요도를 임의로 설정해야 한다.
◦
각 타입별로 경고범위와 위험범위를 지정했고, 데이터 생성방식은 rand로 만들어두지만 이후에 조금 더 현실적인 데이터를 위해 수정할 수 있다.
•
데이터 생성 서버는 12대로 가정한다.
◦
12대의 물리적인 서버는 제공받지 못하므로, AWS EC2의 인스턴스를 활용하기로 했다.
◦
지원받는 금액에 제한이 있으므로, 최소한의 비용을 위해 6대의 Ec2에서 데이터 생성 서버인 Spring boot를 docker container로 2개씩 올리도록 한다. 이에 대해서는 기업측에서도 허가해줬다.
•
데이터 송/수신 설계
◦
생성된 데이터는 모두 데이터를 처리하는 서버측의 DB에 저장되어야 한다.
◦
서버가 데이터를 얼마만큼 보내고 처리할 수 있는지 알아야한다.
◦
데이터를 처리하는 서버에 문제가 생기는 경우, 생성서버의 데이터를 보낼수 없게된다. 이럴때를 대비해서 각 생성서버측에 DB를 놔두고, 서버가 다시 연결되었을때 보내지 못한 데이터를 보내는 전략을 수립해야 한다.
•
데이터 UI
◦
데이터를 보여줌에 있어 다양한 방식이 있지만, FE쪽의 기술스택을 고려해 React와 Chat에 관련된 라이브러리 기술을 사용하기로 진행하기로 했다.
기술스택 선정 및 아키텍쳐 설계(04/17 ~ 04/18)
NOTE
요구사항 명세서에 따른 기술스택 선정 및 아키텍쳐
시스템 아키텍쳐 구조도 (초안)
Springboot
•
해당 프로젝트에 완벽하게 어울리는 기술스택이라 판단되지는 않지만 , 프로젝트의 일정이나 팀원역량을 고려했을 때 가장 익숙한 기술이 좋다고 판단되어 선택하게 되었다.
•
데이터 생성, 데이터 가공, React에 실시간으로 데이터를 보내는 웹소켓을 구현하기 위해 사용한다.
Netty (초기도입 이후 완벽히 Kafka로 대처)
•
데이터 생성주기가 5ms단위의 데이터가 1서버당 50개, 12서버로 보면 600번의 통신이 5ms마다 발생하게 된다. HTTP방식은 header나 다른 요소들이 많아 너무 무겁다고 판단되어 저레벨 수준의 TCP/IP 통신방식으로 보내는 방향으로 조사했다.
•
조사하는 과정에서 Java에서 활용가능한 low level의 네트워크 프로토콜에 중점을 둔 Netty 프레임워크를 발견하였다.
•
TCP와 SSL의 구현을 쉽게해주고, NIO 통신방식과, ByteBuf를 통한 데이터 전송등 짧은 주기로 계속해서 데이터를 보내는 우리 프로젝트에 적합하다고 판단했기에 채택했다.
Kafka
•
kafka를 활용하면 데이터 전송이 실패되는 시나리오나, 대량의 데이터를 더 잘 처리할수 있다고 조사가 되었으며 netty와 둘다 사용이 가능하다기에 채택되었다.
•
초기에는 Netty와 동시 구현을 생각했으나, Kafak로 완전히 대체하게됨
InfluxDB
압도적 1등
•
RDB보다는 대량의 데이터가 짧은시간내에 자주 발생하는 만큼 시계열 DB가 어울리다고 판단하였다. 조사결과 InfluxDB가 가장 대중적이고, Spring과 같이 사용하는 자료가 많아 채택되었다.
배포와 서버구축에 사용하려는 기술들
Jenkins
•
자동배포를 구축하기 위해 사용하며, 기존에 사용했던 기술이라 채택했다.
Docker
•
컨테이너로 배포하기 위해 사용한다.
•
쿠버네티스를 활용해, 배포환경을 구축하는것도 고려했으나 새롭게 배우는 기술들도 많고, 우리 프로젝트에서 다른 서버의 컨테이너를 관리하는건 portainer만으로 충분하다고 생각했기에 제외했다.
Terraform & Ansible
•
여러개의 서버를 구축하는 프로젝트가 처음인 만큼, 어떤 기술과 지식을 알아야하는지 조사했고, 현업에 다니는 지인에게 어떤 방식으로 진행하면 좋을지 조언을 구했다. 그 과정에서 Terraform과 Ansible의 기술을 추천받았다.
•
AWS 여러대의 서버를 구축하는데 있어, 콘솔보다 Terraform으로 관리하면 코드로 작성되기에 수정사항을 추적하기에 좋고, 더 편리하게 생성할 수 있기에 채택했다.
•
Ansible의 경우 조사해본 결과 다수의 서버에 배포하는 작업이나, 설치해야하는 경우, Inventory와 Playbook으로 편리하게 할 수 있기에 채택했다.
데이터 생성 코드 및 Netty통신 구현(04/18 ~ 04/26)
NOTE
데이터 명세서에 따른 데이터 생성코드 작성과 Netty 통신구현
데이터 생성
•
특정시간 간격마다 데이터가 생성되기 때문에 특정시간 마다 실행되는dataGenerationScheduler.scheduleAtFixedRate을 사용했다
•
5ms 단위의 데이터 전송이 서버에 부담이 가는경우를 대비해 데이터를 특정시간 동안 모은뒤, 최대값만 전송해주고 있다.
•
통신에 문제가 없다면 보내는 시간간격을 줄이고 최종적으로 생성시간과 동일하게 전송하는걸 목표로하고 있다.
Netty를 통해 데이터를 전송/수신
•
int, double, String의 모음인 Sensor와 MachineState 데이터의 경우, 용량이 크지않다. 하지만 Image나 Analog의 데이터는 상대적으로 용량이 크고 보내는 주기도 길다.
•
데이터를 수신받을 때, 용량이 큰경우는 그만큼의 최대길이를 할당해야하므로, 하나의 채널에서 크기와 보내는 주기가 제각각인 데이터를 모두 받는것은 비효율적이라 판단해 3개로 나누었다.
◦
Sensor, MachineState → 1024Byte(최대길이), 9997 port 채널
◦
Analog → 1MB(최대길이), 9998 port 채널
◦
Image → 5MB(최대길이), 9999 port 채널
•
데이터 전송 형태는 다음과 같다.
[서버 이름]+ " " + [데이터 타입]+ " " + [데이터 값]+ " " + [데이터 생성시간];
Java
복사
데이터 내용은 “ “로 구분되며, 메시지의 마지막은 \n으로 마무리한다.
Terraform, Ansible 활용한 서버구축(04/27 ~ 05/04)
NOTE
Terrafom을 활용한 서버 설계와, Ansible을 사용한 환경구성!
Terraform을 활용한 서버생성 및 관리
Ansible + Jenkins을 활용한 서버구성 및 배포
데이터 전송량에 따른 과부하 테스트(05/08 ~ 05/16)
NOTE
데이터 생성주기와, Kafka에 전송되는 데이터양을 조절하면서 서버의 성능을 수정한다.
최종 서버 아키텍쳐
Grafana + Cloudwatch + Lambda를 통한 알람구현
CPU 사용량 (외부 카프카서버 2대 더있음)
Kafka Metric 1
Kafka Metric 2
•
저장주기 최적화및, 서버의 성능을 바꿔가며 테스트를 진행했다.
•
기존의 목표인 5ms까지는 도달하지 못했지만 x5수치까지 최적화를 완료했으며, 서버의 구조는 AWS Vcpu제한으로 조금씩 수정했다.