👉 직장에서 만난 사람들의 연락처를 따로 관리하고 싶다면 !
👉 계속해서 쌓이는 명함들 어떻게 관리할지 고민된다면 !
👉 커뮤니티를 통해 다양한 직군에 대해 궁금증을 해결하고 싶다면 !
- 이제 비지너스로 스마트하고 간편하게 관리해 보세요.
🌎 링크 비지너스 바로가기
2022.11.04 ~ 2022.12.16
서비스 런칭 : 2022.12.08
| Part🗂 | Tech⚒️ |
|---|---|
| 🌅Front | |
| ⚙️Back | |
| ⚒️Tool |
| 기술 스택 | 사용이유 |
|---|---|
| AWS Amplify | 테스트 환경 및 피드백 기반 추가작업시 자동배포 환경이 갖추어져 있지 않으면 변경사항이 있을 때마다 다시 배포를 해야하는 번거로움이 생기기 때문에 자동배포 환경이 필요했는데 배포할 도메인 하나만 구매하면 추가적인 비용 없이 자동배포 환경을 갖출 수 있는 AWS Amplify를 사용했다. |
| sockJs/Stomp | 채팅기능에 적합한 브라우저와 웹 서버 사이에 짧은 지연시간, 그리고 크로스 브라우징을 지원하는 API인 Sock.js와 HTTP에서 모델링 되는 Frame 기반 프로토콜 Stomp는 여러개의 채팅방을 개설하는 상황에 적합한 Stomp프로토콜을 사용했다. |
| 기술 스택 | 사용이유 |
|---|---|
| Google Vision API OCR | 명함이미지 내 텍스트를 추출해 해당 값이 입력하기 위해서는 OCR 엔진이 필요하였다. 그래서 Google Vision API (OCR)와 Tesseract OCR의 두 가지 선택지 중에 Google Vision API에서 제공해주는 OCR엔진이 Tesseract OCR 보다 한글의 인식률 및 정확도가 높고 이미지 전처리 과정이 필요없어 적합하다고 판단하여 사용하였다. |
| Google Cloud Storage | 명함첩 및 게시글에 업로드 할 이미지를 저장할 저장소가 필요하였다. OCR 기능 구현에 있어서 Storage에 업로드 된 이미지를 읽어오는 과정을 처리하기 위해서는 외부 호스팅 이미지에 의존하면 안되는 상황이었다. 즉, GCS만을 지원하기에 AWS S3와 Google Cloud Storage 두 가지 선택지중 GCS를 선택하였다. |
| Spring Batch | 기업명, 기업주소는 텍스트로 추출이 불가하여 명함 등록 시 기업 검색 기능을 구현하기로 하였다. 기업정보 오픈 API를 사용 시 한번에 많은 요청이 가는 것을 방지하기 위해 데이터를 DB에 내재화 해두었으며, 오픈API의 정보가 update될 때 DB도 update 될 수 있도록 Spring Batch를 통해 버전관리를 하였다. |
| STOMP | 메시징 방식만 잘 정의한다면 WebSocket 만으로 좋은 Server/Client 소켓 서버를 완성할 수 있으나, STOMP 프로토콜을 이용, 클라이언트와 서버가 전송할 메세지의 유형, 형식, 내용들을 정의하여 개발의 편의성을 높이고 메시지 헤더에 값을 세팅할 수 있어 인증 처리 구현이 가능했다. |
| Redis | 만약 프로젝트의 사용자가 어느정도 확보되면 서버의 갯수가 늘어남에 따라 확장성을 고려하여 메세지 송/수신하는 브로커를 외부로 따로 빼는 것이 맞다고 판단했다. 이벤트 데이터(채팅)를 DB에 저장하기 때문에 미들웨어에는 저장될 필요가 없고 캐시성 데이터면 충분하기 때문에 RabbitMQ, Kafka가 아닌, Redis를 외부브로커로 사용했다. 사용자의 입장 정보, Unread Message Count 등에 대해서 DB로부터 잦은 조회가 일어나는 부분에 대해서는 Buffer(임시 저장 공간)로도 사용했다. |
- 소셜 로그인 (카카오)
- 명함 관리 (OCR)
- 내 일정 관리
- 실시간 1:1 채팅
- 커뮤니티 게시판
- 내 명함 및 프로필 관리
| 소셜로그인 | OCR(명함등록) | 명함 내보내기 |
|---|---|---|
![]() |
![]() |
![]() |
| 일정 관리 | 게시글 작성 | 실시간 채팅 |
![]() |
![]() |
![]() |
✔ Frond-end
화면 새로고침이나 전환 시 랜더링 이슈
커뮤니티 렌더링 이슈
InvalidStateError: The connection has not been established yet
🐞이슈 사항
1.게시글에서 채팅페이지로 이동 후 websocket connect보다 subscribe가 먼저 진행되는 이슈가 발생하여 TypeError도 함께 발생하였다.
🙌문제 해결
1.웹소켓 커넥션 상태를 이용해 웹소켓의 상태가 1일 경우 즉 연결이 성립되고 통신중인 상태일 때 subscribe가 실행되도 구독이 되도록 해보았지만 변함은 없었다.
2.페이지 이동후 마운트 될 때 connect보다 subscirbe가 나중에 진행되도록 setTimeout을 설정하여 해결
(navigate를 먼저 할당하여 해결이 가능하지만 안정적인 작동을 위해 setTimeout 지정)
✔ Back-end
기업 검색 시 Full-text Index
🐞이슈 사항
1. 기업 검색 쿼리문을 Like절을 사용하여 작성 ⇒ JMeter로 성능테스트를 해보니 TPS가 현전히 낮음 ⇒ 개선이 필요하다고 판단
🙌문제 해결
1. LIKE절을 사용했을 때는 테이블을 full scan 하기 때문에 여러 사용자가 동시다발적으로 요청한다면 느려질 수 밖에 없다고 판단
-
FULL TEXT INDEX문으로 대체
-
테스트 결과
📌동시다발적으로 기업 검색 시
- 가상유저 70명 ☑ 평균테스트 시간: 2.3초 감소
- 가상유저 200명 ☑ 평균테스트 시간: 6초 감소
📌 Saturation Point
☑ 200명 👉 800명 증가
WebSocket에서의 보안
🐞이슈 사항
1. <사용자 검증> WebSocket에서의 사용자 검증이 이루어지지 않아 무분별한 HandShake가 가능. 이를 막기 위해 userdetails를 사용하고자 했지만, HTTP와 WebSocket의 헤더는 서로 다른방식이기 때문에 사용자를 식별하기 위한 별도의 인증 처리 구현이 필요하다 판단.
-
<구독 주소> 특정 사용자가 의도적으로 다른 채팅방을 구독할 시, 채팅방 메세지를 받아볼 수 있는 보안적 Issue 발생
🙌문제 해결 -
Jwt를 발급하여 해당 토큰을 Stomphandler에서 메세지를 인터셉트할때 accessor.getFirstNativeHeader("Authorization")로 토큰을 가져오고 별도로 작성한 JwtDecoder 클래스를 통해 토큰 검증 및 사용자 email 추출을 진행하여 정상적인 사용자에 대해 식별하였음
-
@MessageMapping시에도 @Header("Authorization")에 token을 담아와서 사용자를 확인하였으며, 토큰을 통해 유저 정보를 가져올 수 있으므로, 기존에 프론트로부터 sender를 입력받기로 하였던 것을 제외함.(서버에서 메세지 작성자 추출)
-
구독 주소(subscribe destination)를 UUID를 사용하여 설정하여 채팅방Id의 고유성 보장과 동시에 채팅방에 속해있지 않은 유저가 다른 채팅방을 구독하여 채팅메세지를 받아볼 수 없도록 보안 설정
서버 Memory 부족 현상
🐞이슈 사항
1. t2.micro사양을 가진 Ec2 Instance에 Spring Application을 터미널 세션이 끊겨도 실행을 멈추지 않고 동작하도록 하기 위해 nohup으로 배포 (default : 7.6G)
-
서비스 운영 중 이미지 업로드 및 게시글 작성이 안되는 현상 발생
-
Ec2 서버에서 사용 가능한 공간에 대한 정보 조회
-
7.6G 중 7.6G를 모두 사용해서 에러 발생
-
원인: nohup으로 배포시 nohup.out 파일이 생성됨. 프로세스 실행시 출력되는 stdout내용이 이 파일에 기록됨. 프로세스가 실행되는 stdout으로 출력되는 모든 내용이 nohup.out으로 쌓이면서 시간이 지나면 nohup.out 파일 용량이 커지게 됨.
-
로그기록이 필요했기에 nohup.out파일은 꼭 필요하다고 판단
-
nohup.out파일을 날짜별로 생성하여 다른 디렉토리에 따로 저장하여 분리
- 추후 해결방안 : 루트 볼륨 크기 & 파티션 크기 늘리기
| 김석재 | 김승재 | 홍마로 | 황대연 | 김보경 | 서병범 | 정유성 | 최예빈 |
|---|---|---|---|---|---|---|---|
| FE(리더) | FE | FE | FE | BE(부리더) | BE | BE | DESIGNER |
| 🔗 | 🔗 | 🔗 | 🔗 | 🔗 | 🔗 | 🔗 | 📧 choiyebin98@gmail.com |











