聊天服务器分布式改造

目前的聊天室是单节点的,无论是http接口还是socket接口都在同一个进程,无法承受太多人同时在线,容灾性也非常差。因此,一个成熟的IM产品一定是做成分布式的,根据功能分模块,每个模块也使用多个节点并行部署。

1.技术选型

Spring Cloud Alibaba 和 Netflix 都是用于构建分布式系统的工具集,它们在微服务架构中发挥着重要作用,但在多个方面存在差异:
发展与维护

  • Netflix:部分核心组件(如 Eureka、Hystrix)停止更新维护,企业使用有后续风险。
  • Spring Cloud Alibaba:由阿里巴巴开源并持续投入开发,社区活跃,不断迭代优化,能及时修复问题、添加新功能。

核心组件功能

  • Netflix 服务注册与发现(Eureka),负载均衡(Ribbon),熔断与限流(Hystrix),都已经停更。
  • Spring Cloud Alibaba的各种组件处于活跃的开发和维护状态,不断推出新的功能和优化。

生态系统

  • Netflix:早期生态完整,但因组件停更发展受限。
  • Spring Cloud Alibaba:深度集成 Spring Cloud,与阿里巴巴其他开源项目配合好,社区文档和示例丰富,生态发展好。

综上,我们选择Spring Cloud Alibaba( 2021.x 版本**)。**

2.主要服务组件

|---------------------------------------|----------------|
| 组件 | 功能 |
| Nacos | 服务注册与发现组件,配置中心 |
| spring-cloud-starter-gateway | 通信网关 |
| Spring Cloud Alibaba LoadBalancer | 客户端负载均衡器 |
| spring-security-oauth2 | 集中授权中心 |

2.1.Nacos服务发现与配置管理

Nacos 是 Spring Cloud Alibaba 中核心的服务注册与发现组件,同时也具备配置管理功能。除了Nacos,还有**Eureka,Consul,ZooKeeper等有类似功能,**但Nacos同时在这两个方面表现优异,还有一个可视化管理后台,作为首选产品。

2.2.spring-security-oauth2授权中心

spring-security-oauth2作为一个集中授权中心,无论是客户端请求,还是微服务内部的请求,都需要先到它这里进行认证,结合jwt算法,可以生成一个无需服务器管理的token。

Spring Security OAuth2 实现了 OAuth 2.0 协议中的四种授权方式,分别是授权码模式(Authorization Code)、简化模式(Implicit)、密码模式(Resource Owner Password Credentials)和客户端模式(Client Credentials)。下面为你详细介绍这四种授权方式:

授权码模式(Authorization Code)

授权码模式是 OAuth 2.0 中最安全、最常用的授权方式。它适用于有服务器端的应用,通过客户端引导用户到授权服务器进行登录授权,获取授权码,再用授权码换取访问令牌。

简化模式(Implicit)

简化模式是一种简化的授权方式,适用于没有服务器端的客户端应用(如单页应用)。它省略了授权码的步骤,直接在浏览器中获取访问令牌。

密码模式(Resource Owner Password Credentials)

密码模式是一种简单直接的授权方式,适用于受信任的客户端应用。用户直接将自己的用户名和密码提供给客户端,客户端使用这些信息向授权服务器换取访问令牌。

客户端模式(Client Credentials)

客户端模式是一种用于客户端应用自身获取访问令牌的授权方式,不涉及用户的身份信息。适用于客户端应用需要以自己的身份访问资源服务器的场景。

在微服务内部授权上,本文使用客户端模式。当微服务之间以服务自身的身份进行交互,且不需要区分用户身份时,客户端模式是一个简单、安全、高效的授权方式。可以使用 OAuth 2.0 协议的客户端模式来管理服务之间的访问权限。

在客户端登录验证上,本文使用密码模式,结合jwt算法,实现无状态的授权。

3.模块划分

对于一个聊天软件,按照功能进行划分,先简单划分为用户,web,socket模块。后面根据需要再进行细化。

主要目标,除了聊天这种实时性要求,以及客户端推送这种需要服务器主动发送消息以外,其他逻辑尽可能走http,实现负载均衡。 架构图如下:

客户端统一访问gateway网关,通过账号密码向授权中心认证通过后,得到一个token,后续所有http请求都需要带上此header。http登录成功之后,服务器还会根据负载均衡策略选择一个socket节点,作为客户端聊天的主要通信网关,用户在这次登录的生命周期只会绑定该节点,而其他http请求则会被分散到不同模板的不同节点。

4.第三方中间件

|-------|--------------------|
| 中间件 | 作用 |
| mysql | 用户,讨论群,消息等数据的持久化方案 |
| minio | 头像,多媒体消息的文件存储系统 |
| redis | 用户数据快速缓存 |
| nacos | 服务注册发现,配置管理 |

由于使用的中间件比较多,本文使用docker-compose进行集中化配置,配置如下:

复制代码
version: '3.3'
 
services:
  db:
    image: mysql:latest
    container_name: im-mysql
    environment:
      MYSQL_PASSWORD: '123456'
      MYSQL_ROOT_PASSWORD: '123456'
    ports:
      - "3306:3306"
    volumes:
      - ./data/mysql/data:/var/lib/mysql
    restart: always
    networks:
      - im-network
  nacos:
    image: nacos/nacos-server:v2.3.1
    container_name: im-nacos
    environment:
      - PREFER_HOST_MODE=hostname
      - MODE=standalone
      - NACOS_AUTH_IDENTITY_KEY=serverIdentity
      - NACOS_AUTH_IDENTITY_VALUE=security
      - NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
    ports:
      - "8848:8848"
      - "9848:9848"
    networks:
      - im-network 

  minio:
    image: minio/minio:latest
    container_name: im-s3
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin
    command: server --console-address ":9001" /data    
    volumes:
      - ./data/minio:/data
    restart: always
    networks:
      - im-network

  redis:
    image: redis:latest
    container_name: im-redis
    ports:
      - "6379:6379"
    volumes:
      - ./data/redis:/data
    restart: always
    networks:
      - im-network      
networks:
  im-network:
     driver: bridge

全部代码已在github上托管

服务端代码请移步 --> 聊天室服务器

客户端代码请移步 --> 聊天室客户端

相关推荐
佳腾_3 小时前
【分布式系统中的“瑞士军刀”_ Zookeeper】二、Zookeeper 核心功能深度剖析与技术实现细节
分布式·zookeeper·云原生·集群管理·命名服务
FISCO_BCOS3 小时前
分布式数字身份:迈向Web3.0世界的通行证 | 北京行活动预告
分布式·web3
猎人everest7 小时前
Spring Boot集成Spring Cloud 2024(不使用Feign)
java·spring boot·spring cloud
搞不懂语言的程序员8 小时前
Kafka的Topic分区数如何合理设置?
分布式·kafka
NON-JUDGMENTAL9 小时前
Hadoop 集群基础指令指南
大数据·hadoop·分布式
头顶秃成一缕光10 小时前
JVM快速入门
java·linux·jvm·ide·spring·spring cloud·servlet
hnlucky12 小时前
hadoop伪分布式模式
大数据·hadoop·分布式
IT技术分享社区12 小时前
电脑干货:开源免费的QQ空间说说下载工具GetQzonehistory
电脑软件·电脑技巧·qq
zhang238390615416 小时前
Kafka-可视化工具-Offset Explorer
分布式·kafka
fjkxyl16 小时前
Kafka 消息可靠性深度解析:大流量与小流量场景下的设计哲学
分布式·kafka