From 567081c1fcc46f67641f2fae70fc7319d4024c66 Mon Sep 17 00:00:00 2001 From: konenet Date: Sat, 11 Dec 2021 22:25:13 +0800 Subject: [PATCH] feat: deploy on the docker by docker-compose --- README.md | 25 +++++++++++++++++++++++++ config.toml | 2 +- deployments/docker/Dockerfile | 1 + deployments/docker/docker-compose.yml | 22 ++++++++++++++++++++++ deployments/docker/nginx.conf | 10 +++++++++- internal/server/server.go | 7 ++++++- pkg/protocol/message.proto | 2 +- 7 files changed, 65 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0855134..bc5233d 100644 --- a/README.md +++ b/README.md @@ -200,11 +200,36 @@ docker build -t konenet/gochat:1.0 . 需要部署nginx进行反向代理,mysql保存数据,1个或者多个后端服务。 * 在config.toml中配置分布式消息队列 将msgChannelType中的channelType修改为kafka,就为分布式消息队列。需要填写消息队列对应的地址和topic +```toml +appName = "chat_room" + +[mysql] +host = "mysql8" +name = "go-chat-message" +password = "thepswdforroot" +port = 3306 +tablePrefix = "" +user = "root" + +[log] +level = "debug" +path = "logs/chat.log" + +[staticPath] +filePath = "web/static/file/" + +[msgChannelType] +channelType = "kafka" + +kafkaHosts = "kafka:9092" +kafkaTopic = "go-chat-message" +``` * 启动服务 通过deployments/docker下的docker-compose.yml进行启动。 ``` docker-compose up -d ``` +* 注意:分布式部署后,上传的文件视频等,可能会因为负载到不同的机器上,导致文件找不到的情况,所以需要一个在线或者分布式文件服务器。 ## 代码结构 ``` diff --git a/config.toml b/config.toml index a588516..73d767b 100644 --- a/config.toml +++ b/config.toml @@ -18,5 +18,5 @@ filePath = "web/static/file/" [msgChannelType] channelType = "gochannel" -kafkaHosts = "myAddress:9092" +kafkaHosts = "kafka:9092" kafkaTopic = "go-chat-message" \ No newline at end of file diff --git a/deployments/docker/Dockerfile b/deployments/docker/Dockerfile index 827dedc..4e58973 100644 --- a/deployments/docker/Dockerfile +++ b/deployments/docker/Dockerfile @@ -1,5 +1,6 @@ FROM hub.c.163.com/public/centos:7.0 RUN [ "mkdir", "/usr/local/gochat" ] +RUN [ "mkdir", "-p", "/usr/local/gochat/web/static/file" ] WORKDIR /usr/local/gochat COPY ../../bin/chat /usr/local/gochat COPY ../../config.toml /usr/local/gochat diff --git a/deployments/docker/docker-compose.yml b/deployments/docker/docker-compose.yml index ff87639..094e612 100644 --- a/deployments/docker/docker-compose.yml +++ b/deployments/docker/docker-compose.yml @@ -1,6 +1,24 @@ version: '3' services: + zookeeper: + image: zookeeper + ports: + - 2182:2181 + + kafka: + image: wurstmeister/kafka + ports: + - 9092:9092 + environment: + KAFKA_BROKER_ID: 0 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.1.12:9092 # 物理机地址 + KAFKA_CREATE_TOPICS: "go-chat-message:2:0" # kafka启动后初始化一个有2个partition(分区)0个副本名叫go-chat-message的topic + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092 + depends_on: + - zookeeper + mysql8: image: mysql:8.0 container_name: mysql8 @@ -43,8 +61,10 @@ services: - 8888:8888 links: - mysql8 + - kafka depends_on: - mysql8 + - kafka gochat1: image: konenet/gochat:1.0 @@ -52,5 +72,7 @@ services: container_name: gochat1 links: - mysql8 + - kafka depends_on: - mysql8 + - kafka diff --git a/deployments/docker/nginx.conf b/deployments/docker/nginx.conf index b90c128..4199f0e 100644 --- a/deployments/docker/nginx.conf +++ b/deployments/docker/nginx.conf @@ -29,6 +29,12 @@ http { #include /etc/nginx/conf.d/*.conf; + #websocket配置 + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + upstream chat { ip_hash; server gochat:8888; @@ -39,10 +45,12 @@ http { listen 80; server_name chat; location / { - proxy_pass http://chat; + proxy_pass http://chat; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; } } } \ No newline at end of file diff --git a/internal/server/server.go b/internal/server/server.go index ee81c7c..672b7b5 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -70,7 +70,12 @@ func (s *Server) Start() { if msg.To != "" { // 一般消息,比如文本消息,视频文件消息等 if msg.ContentType >= constant.TEXT && msg.ContentType <= constant.VIDEO { - saveMessage(msg) + // 保存消息只会在存在socket的一个端上进行保存,防止分布式部署后,消息重复问题 + _, exits := s.Clients[msg.From] + if exits { + saveMessage(msg) + } + if msg.MessageType == constant.MESSAGE_TYPE_USER { client, ok := s.Clients[msg.To] if ok { diff --git a/pkg/protocol/message.proto b/pkg/protocol/message.proto index 8fded48..5d130b1 100644 --- a/pkg/protocol/message.proto +++ b/pkg/protocol/message.proto @@ -8,7 +8,7 @@ message Message { string to = 4; // 发送给对端用户的uuid string content = 5; // 文本消息内容 int32 contentType = 6; // 消息内容类型:1.文字 2.普通文件 3.图片 4.音频 5.视频 6.语音聊天 7.视频聊天 - string type = 7; // 如果是心跳消息,该内容为heatbeat + string type = 7; // 消息传输类型:如果是心跳消息,该内容为heatbeat,在线视频或者音频为webrtc int32 messageType = 8; // 消息类型,1.单聊 2.群聊 string url = 9; // 图片,视频,语音的路径 string fileSuffix = 10; // 文件后缀,如果通过二进制头不能解析文件后缀,使用该后缀