diff --git a/.aws/ecs-task-definition-chat.json b/.aws/ecs-task-definition-chat.json index e3f3ee8..b7d6a93 100644 --- a/.aws/ecs-task-definition-chat.json +++ b/.aws/ecs-task-definition-chat.json @@ -1,9 +1,9 @@ { - "taskDefinitionArn": "arn:aws:ecs:ap-northeast-2:008971651785:task-definition/cloud6-chat-server:13", + "taskDefinitionArn": "arn:aws:ecs:ap-northeast-2:008971651785:task-definition/cloud6-chat-server", "containerDefinitions": [ { "name": "cloud6-chat", - "image": "008971651785.dkr.ecr.ap-northeast-2.amazonaws.com/cloud6-chat:938df75d3687680cabd6c3fb4e6137181bd25aa7", + "image": "008971651785.dkr.ecr.ap-northeast-2.amazonaws.com/cloud6-chat:230145b40161b7fb205158b3330a8805ed60d692", "cpu": 0, "portMappings": [ { @@ -15,7 +15,16 @@ } ], "essential": true, - "environment": [], + "environment": [ + { + "name": "JAEGER_PORT", + "value": "6831" + }, + { + "name": "JAEGER_HOST", + "value": "jaeger.cloud6-chat" + } + ], "mountPoints": [], "volumesFrom": [], "logConfiguration": { @@ -34,7 +43,6 @@ "family": "cloud6-chat-server", "executionRoleArn": "arn:aws:iam::008971651785:role/ecsTaskExecutionRole", "networkMode": "awsvpc", - "revision": 13, "volumes": [], "status": "ACTIVE", "requiresAttributes": [ @@ -71,13 +79,11 @@ "requiresCompatibilities": [ "FARGATE" ], - "cpu": "4096", - "memory": "8192", + "cpu": "1024", + "memory": "2048", "runtimePlatform": { "cpuArchitecture": "X86_64", "operatingSystemFamily": "LINUX" }, - "registeredAt": "2024-08-02T23:46:22.568Z", - "registeredBy": "arn:aws:iam::008971651785:user/chaeri9813", "tags": [] -} +} \ No newline at end of file diff --git a/chat/build.gradle b/chat/build.gradle index 8accc18..5b56ec4 100644 --- a/chat/build.gradle +++ b/chat/build.gradle @@ -41,6 +41,7 @@ dependencies { implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.4' implementation platform('software.amazon.awssdk:bom:2.20.85') implementation 'software.amazon.awssdk:dynamodb-enhanced' + implementation 'io.opentracing.contrib:opentracing-spring-jaeger-web-starter:3.3.1' compileOnly 'org.projectlombok:lombok' // developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' diff --git a/chat/src/main/resources/application.properties b/chat/src/main/resources/application.properties index 81e7d4a..f046315 100644 --- a/chat/src/main/resources/application.properties +++ b/chat/src/main/resources/application.properties @@ -19,4 +19,9 @@ aws.accessKeyId=${AWS_ACCESS_KEY_ID} aws.secretAccessKey=${AWS_SECRET_ACCESS_KEY} aws.region=ap-northeast-2 +### Jaeger ### +opentracing.jaeger.service-name=chat +opentracing.jaeger.udp-sender.host=${JAEGER_HOST} +opentracing.jaeger.udp-sender.port=${JAEGER_PORT} + server.servlet.session.timeout=10m diff --git a/performance_test/Dockerfile b/performance_test/Dockerfile new file mode 100644 index 0000000..fe927cf --- /dev/null +++ b/performance_test/Dockerfile @@ -0,0 +1,14 @@ +FROM python:3.12-slim +RUN ln -snf /usr/share/zoneinfo/Asia/Seoul /etc/localtime +RUN echo Asia/Seoul > /etc/timezone + +WORKDIR /locust + +COPY src/ ./src/ +COPY pyproject.toml ./ + +RUN pip install poetry +RUN poetry install + +EXPOSE 8089 +ENTRYPOINT ["poetry", "run", "locust", "-f", "src/load/locustfile.py", "--host", "http://0.0.0.0:8089"] \ No newline at end of file diff --git a/performance_test/src/common/stomp.py b/performance_test/src/common/stomp.py index 202b1ed..7604ead 100644 --- a/performance_test/src/common/stomp.py +++ b/performance_test/src/common/stomp.py @@ -5,8 +5,9 @@ class StompClient: - def __init__(self, host, port, endpoint) -> None: - self.__ws_uri = f"ws://{host}:{port}/{endpoint}" + def __init__(self, host, endpoint) -> None: + self.__ws_uri = f"ws://{host}/{endpoint}" + self.__ws = websocket.WebSocket() def __del__(self): self.close() @@ -18,76 +19,95 @@ def close(self): def connect(self): start_time = time.time() - try: - self.__ws = websocket.create_connection(self.__ws_uri) - self.__ws.send(stomper.connect()) - # self.__ws.recv() + self.__ws.connect(self.__ws_uri, timeout=100000) + self.__ws.send("CONNECT\naccept-version:1.0,1.1,2.0\n\n\x00\n") + self.__ws.recv() - except Exception as e: - total_time = int((time.time() - start_time) * 1000) - # events.request.fire(request_type="STOMP", name="connect", response_time=total_time, exception=e) + # try: + # # self.__ws = websocket.create_connection(self.__ws_uri) + # self.__ws.connect(self.__ws_uri, timeout=100000) + # self.__ws.send("CONNECT\naccept-version:1.0,1.1,2.0\n\n\x00\n") + # # self.__ws.send(stomper.connect()) + # self.__ws.recv() + + # except Exception as e: + # total_time = int((time.time() - start_time) * 1000) + # events.request.fire(request_type="STOMP", name="connect", response_time=total_time, exception=e) - else: - total_time = int((time.time() - start_time) * 1000) - # events.request.fire(request_type="STOMP", name="connect", response_time=total_time) + # else: + # total_time = int((time.time() - start_time) * 1000) + # events.request.fire(request_type="STOMP", name="connect", response_time=total_time) def subscribe(self, destination, id): start_time = time.time() - try: - self.__ws.send(stomper.subscribe(destination, id)) - # self.__ws.recv() + self.__ws.send(stomper.subscribe(destination, id)) + + # try: + # self.__ws.send(stomper.subscribe(destination, id)) + # # self.__ws.recv() - except Exception as e: - total_time = int((time.time() - start_time) * 1000) - # events.request.fire(request_type="STOMP", name="subscribe", response_time=total_time, exception=e) + # except Exception as e: + # total_time = int((time.time() - start_time) * 1000) + # events.request.fire(request_type="STOMP", name="subscribe", response_time=total_time, exception=e) - else: - total_time = int((time.time() - start_time) * 1000) - # events.request.fire(request_type="STOMP", name="subscribe", response_time=total_time) + # else: + # total_time = int((time.time() - start_time) * 1000) + # events.request.fire(request_type="STOMP", name="subscribe", response_time=total_time) def send(self, destination, message): start_time = time.time() - try: - self.__ws.send(stomper.send(destination, message)) - # self.__ws.recv() + self.__ws.send(stomper.send(destination, message, content_type="application/json")) + + # try: + # self.__ws.send(stomper.send(destination, message, content_type="application/json")) + # # self.__ws.recv() - except Exception as e: - total_time = int((time.time() - start_time) * 1000) - # events.request.fire(request_type="STOMP", name="send", response_time=total_time, exception=e) + # except Exception as e: + # total_time = int((time.time() - start_time) * 1000) + # events.request.fire(request_type="STOMP", name="send", response_time=total_time, exception=e) - else: - total_time = int((time.time() - start_time) * 1000) - # events.request.fire(request_type="STOMP", name="send", response_time=total_time) + # else: + # total_time = int((time.time() - start_time) * 1000) + # events.request.fire(request_type="STOMP", name="send", response_time=total_time) def receive(self): start_time = time.time() + message = "" - try: - message = self.__ws.recv() + message = self.__ws.recv() - except Exception as e: - total_time = int((time.time() - start_time) * 1000) - # events.request.fire(request_type="STOMP", name="receive", response_time=total_time, exception=e) + # try: + # # print("try...") + # message = self.__ws.recv() + + # except Exception as e: + # print("except:", e) + # total_time = int((time.time() - start_time) * 1000) + # events.request.fire(request_type="STOMP", name="receive", response_time=total_time, exception=e) - else: - total_time = int((time.time() - start_time) * 1000) - # events.request.fire(request_type="STOMP", name="receive", response_time=total_time, response_length=len(message)) + # else: + # print('else...') + # total_time = int((time.time() - start_time) * 1000) + # events.request.fire(request_type="STOMP", name="receive", response_time=total_time, response_length=len(message)) + # print("Received message:", message) return message def disconnect(self): start_time = time.time() - try: - self.__ws.send(stomper.disconnect()) - # self.__ws.recv() + self.__ws.send(stomper.disconnect()) + + # try: + # self.__ws.send(stomper.disconnect()) + # # self.__ws.recv() - except Exception as e: - total_time = int((time.time() - start_time) * 1000) - # events.request.fire(request_type="STOMP", name="disconnect", response_time=total_time, exception=e) + # except Exception as e: + # total_time = int((time.time() - start_time) * 1000) + # events.request.fire(request_type="STOMP", name="disconnect", response_time=total_time, exception=e) - else: - total_time = int((time.time() - start_time) * 1000) - # events.request.fire(request_type="STOMP", name="disconnect", response_time=total_time) + # else: + # total_time = int((time.time() - start_time) * 1000) + # events.request.fire(request_type="STOMP", name="disconnect", response_time=total_time) diff --git a/performance_test/src/load/locustfile.py b/performance_test/src/load/locustfile.py index f7f2ebc..fffcb04 100644 --- a/performance_test/src/load/locustfile.py +++ b/performance_test/src/load/locustfile.py @@ -11,9 +11,8 @@ class ChatLoadTestUser(User): - host = "localhost" - port = 8080 - endpoint = "chat" + host = "cloud6-lb-997344652.ap-northeast-2.elb.amazonaws.com" + endpoint = "ws" vuser = 6 @@ -25,9 +24,9 @@ def on_start(self): self.__stomp_clients: list[StompClient] = [] for i in range(self.vuser): - self.__stomp_clients.append(StompClient(self.host, self.port, self.endpoint)) + self.__stomp_clients.append(StompClient(self.host, self.endpoint)) self.__stomp_clients[i].connect() - self.__stomp_clients[i].subscribe(f"/topic/chat/{self.room_id}", f"user{i}") + self.__stomp_clients[i].subscribe(f"/topic/{self.room_id}", f"user{i}") def on_stop(self): for i in range(self.vuser): @@ -35,19 +34,25 @@ def on_stop(self): @task def send_receive_hello(self): - start_time = time.time() - - payload = json.dumps({ - "chatRoomId": self.room_id, - "type": "MESSAGE", - "createdBy": "user0", - "text": "Hello, world!", - "createdAt": datetime.now().strftime("%Y-%m-%dT%H:%M:%S") - }) - self.__stomp_clients[0].send("/topic/chat", payload) - - for i in range(1, self.vuser): - msg = self.__stomp_clients[i].receive() - - total_time = int((time.time() - start_time) * 1000) - self.environment.events.request.fire(request_type="STOMP", name="send_receive_hello", response_time=total_time, response_length=len(msg)) + try: + start_time = time.time() + + payload = json.dumps({ + "roomId": self.room_id, + "memberId": f"00000", + "type": "MESSAGE", + "createdBy": "user0", + "comment": "Hello, world!", + "createdAt": datetime.now().strftime("%Y-%m-%dT%H:%M:%S") + }) + self.__stomp_clients[0].send(f"/app/chat/{self.room_id}", payload) + + for i in range(self.vuser): + msg = self.__stomp_clients[i].receive() + + total_time = int((time.time() - start_time) * 1000) + + except Exception as e: + self.environment.events.request.fire(request_type="STOMP", name="send_receive_hello", response_time=total_time, response_length=0, exception=e) + else: + self.environment.events.request.fire(request_type="STOMP", name="send_receive_hello", response_time=total_time, response_length=len(msg))