{"id":15014295,"url":"https://github.com/a2888409/face2face","last_synced_at":"2025-05-16T00:05:48.113Z","repository":{"id":201448972,"uuid":"50320463","full_name":"a2888409/face2face","owner":"a2888409","description":"基于netty的异步非阻塞实时聊天(IM)服务器。","archived":false,"fork":false,"pushed_at":"2019-04-10T08:20:49.000Z","size":3287,"stargazers_count":1537,"open_issues_count":10,"forks_count":679,"subscribers_count":132,"default_branch":"master","last_synced_at":"2025-04-08T11:08:18.664Z","etag":null,"topics":["netty","nio"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/a2888409.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-01-25T02:27:50.000Z","updated_at":"2025-04-03T06:11:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"6231e4fe-396e-4b77-ab4c-4843edea5b7f","html_url":"https://github.com/a2888409/face2face","commit_stats":null,"previous_names":["a2888409/face2face"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a2888409%2Fface2face","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a2888409%2Fface2face/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a2888409%2Fface2face/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a2888409%2Fface2face/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/a2888409","download_url":"https://codeload.github.com/a2888409/face2face/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254442854,"owners_count":22071878,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["netty","nio"],"created_at":"2024-09-24T19:45:25.964Z","updated_at":"2025-05-16T00:05:47.816Z","avatar_url":"https://github.com/a2888409.png","language":"Java","funding_links":[],"categories":["网络编程"],"sub_categories":["Spring Cloud框架"],"readme":"# face2face\n![image](https://github.com/a2888409/face2face/blob/master/arch.png)\u003cbr\u003e \n`auth服务`：负责登录认证。\u003cbr\u003e \n`gate服务`：负责客户端接入，也是服务器和客户端通信的媒介。\u003cbr\u003e \n`logic服务`：负责处理各种业务逻辑。\u003cbr\u003e\n\n为以后将服务设计为**水平可扩展**的服务准备，将整个服务拆分为3个进程。\u003cbr\u003e\n实现基本功能后的目标是将每个服务设计为可水平扩展的集群，并且重点放在架构上的优化而不是逻辑功能上。\u003cbr\u003e\n\n## **一、QuicksStart**:\n**(a)启动服务器:**\u003cbr\u003e\n\n 1. 使用intellij `maven方式`导入该工程，执行`mvn clean compile`\u003cbr\u003e\n 2. 在对应模块的resources目录下配置auth、logic服`redis数据库地址`。\u003cbr\u003e\n 3. 启动redis服务：thirdparty中附带了一个windows cmd命令行可以直接启动的redis进程。只需用cmd进入该目录，执行：`redis-server.exe redis.windows.conf`\u003cbr\u003e\n 4. 打开intellij的debug/Run configuration根据工程路径重新配置auth logic gate服务启动项**program argument**的`-cfg`选项：(比如工程clone在了E盘code目录，那么就把logic的启动项改为-cfg E:\\code\\face2face\\logic\\src\\main\\resources\\logic.xml)，auth、gate同理。\u003cbr\u003e\n 5. 按顺序启动`logic`、`auth`、`gate服务`(因服务间断线重连暂时未加入)\u003cbr\u003e\n\u003cbr\u003e\n\n**(b)启动客户端**：\u003cbr\u003e\n测试注册和登录功能，以及单聊功能(建议跟踪断点)：\u003cbr\u003e\n\n - 按照quickstart流程依次启动服务器后，再启动client模块的下的客户端(Client类)，服务便会自动执行注册，登录的流程，并每隔100ms给自己发送聊天信息。\u003cbr\u003e\n\n## **二、添加业务逻辑**\u003cbr\u003e\n - `协议流动方式介绍`：客户端先连接gate，gate服务根据客户端发送的协议类型转发到auth服或者logic，到达auth或者logic之后，IO线程将消息dispatch到后端worker线程处理。\u003cbr\u003e\n - `定制业务逻辑`：\u003cbr\u003e\n    - 只需在三个地方注册协议：protobuf模块的**ParseRegistryMap**，gate模块的**TransferHandlerMap**，最后是根据协议类型在auth模块或者logic模块的**HandlerManager**注册即可。注意：HandlerManager注册的是协议最终处理的业务逻辑。\u003cbr\u003e\n    - 在protobuf模块对应**.proto**文件添加你自己定义的协议，执行**proto.bat**即可生成对应pb文件。\u003cbr\u003e\n\n## **三、压力测试**\u003cbr\u003e\n 1. client模块中的`client.Client`类提供了进行压力测试的方法，可以修改启动客户端连接的数量`Client.clientNum`，以及每秒向服务器发送的协议的频率`Client.frequency`进行压力测试。\u003cbr\u003e\n 2. CPU 8核E3-1231v3， 每个服务分配1G的堆内存，启动5000个客户端后(需要一定时间)，不停给自己发送单聊协议，发现auth、logic、gate服务占用的cpu非常低，客户端能够立即收到响应。对应的TPS统计将在后续加入。\u003cbr\u003e\n\n## **四、水平扩展思路(processing)**\u003cbr\u003e\n实际上最简单的做法，就是利用`消息中间件`对服务之间的调用进行**解耦**，这里以消息中间件RocketMQ为例子：\n```\n    client(Producer) -\u003e  gate(Consumer)\n```\n所有用户我们都可以看做是**生产者**，用户操作对应生产者产生消息，gate网关服此时看做是**消费者**订阅用户产生的消息。我们使用RocketMQ的`顺序消息`特性，保证同个用户的消息都转发到同一个消息队列，这样就保证了同个用户操作的先后。\n```\n    gate(Producer)   -\u003e  auth(Consumer)\n    gate(Producer)   -\u003e  logic(Consumer)\n```\n网关服同时又可以看做是生产者，他接收到用户请求后产生逻辑操作消息，这些逻辑操作消息根据不同的类型，又可以被auth服，logic服订阅。auth，logic收到订阅的消息，此时才进行真正的消费。\u003cbr\u003e\n**使用集群模式，消费者是可以任意水平扩展的，rocketmq天生的优势保证了只要生产者消息不丢，即使某个消费者挂了，消息也能够被集群中其他consumer正确消费，但是消费的幂等性要自己保证。**\n\n\n\n\n\n\n\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa2888409%2Fface2face","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fa2888409%2Fface2face","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa2888409%2Fface2face/lists"}