Kubernetes + Openresty+OpenIM

1. 关于

  最近公司需要,研究了openim,有点麻烦,记录一下

1.1. 文档

  开源地址:https://github.com/OpenIMSDK

  • 官方文档:

  https://doc.rentsoft.cn/#/?id=我们的使命

  • api接口文档:

  https://doc.rentsoft.cn:8000/swagger/index.html

1.2. 环境依赖

OpenIM使用的组件包含MQ和各种数据库组件,保证系统当前可用内存在2G及以上,官方使用docker版本为20.10.14,docker-compose版本为1.24.1,如果用户的系统没有安装docker以及docker-compose可以参照docker以及docker-compose环境搭建。

 

1.3. 开放端口

IM端口

说明

操作

TCP:10001

ws协议,消息端口,比如消息发送,推送等。

端口放行或nginx反向代理,关闭防火墙

TCP:10002

api端口,比如用户、好友、群组等接口。

端口放行或nginx反向代理,关闭防火墙

TCP:10003

ws协议,针对jssdk的专用端口。

端口放行或nginx反向代理,关闭防火墙

TCP:10004

demo使用的用户注册登录端口。

端口放行或nginx反向代理,关闭防火墙

TCP:10005

选择minio存储时需要开通。(openIM的demo默认使用minio存储)

端口放行或nginx反向代理,关闭防火墙

TCP:10006

管理后台api端口,需要管理后台服务时开通。

端口放行或nginx反向代理,关闭防火墙

注:如果使用nginx做反向代理,则只需要开放443端口即可,进行中转。

 

1.4. 服务分工

1、ETCD(version:{"etcdserver":"3.3.8","etcdcluster":"3.3.0"})//服务注册与发现

2、MySQL(version:5.7)//用户业务信息以及管理后台查询消息使用

3、MongoDB(version:4.0.28)//线上消息存储

4、Redis(version:redis_version:7.0.0)//业务信息缓存,以及seq缓存

5、Kafka(version:kafka_2.13-2.8.1,依赖于组件zookeeper(version: 3.4.13-2d71af4dbe22557fda74f9a9b4309b15a7487f03))//消息队列,消息总线解耦

6、Minio(version:minio version RELEASE.2022-05-26T05-48-41Z)//私有化对象存储服务,用于图片、语音、文件等存储在自己的服务器中(注:如果使用三方云服务器存储媒体文件可不搭建)

 

2. openim服务部署

2.1. 部署

2.1.1. 下载代码

  git clone https://github.com/OpenIMSDK/Open-IM-Server.git

 

2.1.2. 修改配置文件

  配置文件路径:config/config.yaml

    •   mysql配置修改(必须):

      dbMysqlAddress: [xxx.xxx.xxx.xxx:13306 ]

      # 不要采用127.0.0.1,则无法发送消息,没有任何报错;就算你mysql搭建在本地也不行,不知道为啥

    •   minio配置修改(必须):

      endpoint: http://10.0.22.124:10005 #minio外网ip 这个ip是给客户端访问的

         endpointInner: http://10.0.22.124:10005 #minio内网地址 如果im server 可以通过内网访问到 minio就可以填写

2.1.3. 部署

  cd Open-IM-Server

  docker-compose up -d  

 

2.1.4. 镜像查看

 

2.1.5. 脚本检测

  • docker_check_service.sh

  qiteck@logic2:~/program/open_im/Open-IM-Server/script$ sudo ./docker_check_service.sh

  openImSdkWsPort service does not start normally,not initiated port is 10003, 这个没有开启的话,目前看起来是没有问题

  • check_all.sh

  qiteck@logic2:~/program/open_im/Open-IM-Server/script$ sudo ./check_all.sh

  

  openImSdkWsPort service does not start normally,not initiated port is 10003, 这个没有开启的话,目前看起来是没有问题

 

2.1.6. URL检测

  看下该URL:http://xxx.xxx.xxx.xxx:10004/demo/login, 是否返回这个:

  {

       "errCode": 10001,

        "errMsg": "EOF"

  }

  返回这个,表示网络是通的,只是参数是错误的,没有权限

 

2.2. 遇到问题

2.2.1. check_all的时候提示10001异常

  等一伙,等启动完成一般就没有问题了。长期这个问题的话,看下日志

2.2.2. etcd-endpoints://0xc0005b6540/127.0.0.1:2379",=>rpc error: code = DeadlineExceeded

  open im无法共用k8s的etcd,需要重新搭建。

2.2.3. Couldn't resolve host name. Please check the domain

  是启动还没有完成的意思,等等就好了

2.2.4. mongo提示WiredTiger.wt: fatal read error: WT_ERROR: non-specific WiredTiger error

  删除/component/mongodb的数据就可以正

2.2.5. openImSdkWsPort service does not start normally,not initiated port is 10003

  这个错误是无所谓的,sdk ws都可以不需要配置

2.2.6. 服务器清空redis的缓存,导致客户端发送消息无法被对方接收到,并可能有相关提示WS ReadMsg error   userIP 10.0.22.112:50163 userUid platform error websocket

  确认的规避方法:客户端app需要杀掉,重新安装才行。

  猜想思路:redis和客户端都存储了一些ws的相关信息,这些信息在服务器上没有永久存储,redis清空了以后,服务器找不到相关ws信息,导致客户端发送对方收不到;而重装以后,客户端也没有了ws信息,这时候会重新找服务器沟通,重建ws相关信息。

  解决方案:

    1. 客户端每次启动不缓存数据,客户端进一步看下问题

    2. redis不能清空

 

2.2.7. 使用k8setcd,报错retrying of unary invoker failed

  k8s的etcd服务是一个https服务,而openim只可以连接http协议

  另外k8s的etcd有限制ip连接,需要改进k8s的etcd配置部署

  我没有去研究怎么使用k8s的etcd,而是另外搭建一个etcd服务器

 

2.2.8. 使用k8setcd,报错/demo/login返回{"errCode": 10005,"errMsg": "“}

  原因是因为users表里面没有对应的账号信息。

  registers里面有没有和这个错误无关

 

2.2.9. imdb.GetUserByUserID failed record not found

  详细错误信息是这样:

  2022-07-27 09:41:31.424^[[36m [INFO] [PID:29] [FilePath:auth/auth.go:132] [OperationID:EF8C265E-F869-41B4-A327-94E8619F568A] ^[[0m[UserToken return  {{802 EF8C265E-F869-41B4-A327-94E8619F568A imdb.GetUserByUserID failed record not foundtest3} {test3  0}}]

  2022-07-27 09:41:31.424^[[31m [ERRO] [PID:522] [FilePath:register/login.go:74] [OperationID:EF8C265E-F869-41B4-A327-94E8619F568A] ^[[0m[request get user token test3 err ]

  原因是因为users表里面没有对应的账号信息。

  registers里面有没有和这个错误无关

 

2.2.10. 抓包显示handshake failed

  如果是这个接口http://10.0.22.124:10004/demo/login抓包显示handshake failed,可以采用proxyman试着请求一下 post http://10.0.22.124:10004/demo/login,看是否返回这个:

  {

      "errCode": 10001,

      "errMsg": "EOF"

  }

  返回这个,表示网络是通的,只是参数是错误的,没有权限

  这个错误最后发现是openim不支持采用proxyman进行代理,不能proxyman的证书

 

2.2.11. 此服务器的证书无效。您可能正在连接到一个伪装成“api.test.magefitness.com”的服务器,这会威胁到您的机密信息的安全。

  如果确定证书没有问题的情况下,是否有开启proxyman中转抓包,openim会验证证书的有效性,不能中间人攻击。

  openim不支持采用proxyman进行代理,不能proxyman的证书

 

2.2.12. /openim/?location= HTTP/1.1" 404 159 "-" "MinIO (ios; arm64) minio-go/v7.0.22

  这个就是说吗minio的proxy设置的有问题,需要单独配置,需要/转发,不能设置其他path

  server {

          listen 443;

          server_name storage.rentsoft.cn;

 

 

      location / {

          proxy_pass http://127.0.0.1:10005;

          proxy_set_header X-Real-IP $remote_addr;

          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

          proxy_set_header X-Forwarded-Proto $scheme;

          proxy_set_header Host $http_host;

          proxy_http_version 1.1;

      }

3. k8s+openresty https转发

3.1. 参考文档

  参考官方文档: https://doc.rentsoft.cn/#/v2/server_deploy/nginx_config

3.2. openim配置

  假设openim服务部署在10.17.0.94机器上

server {

    listen 773 ssl;

    server_name  localhost;

     ssl_certificate   /usr/local/openresty/nginx/cert/primary.pem;

    ssl_certificate_key  /usr/local/openresty/nginx/cert/key.pem;

    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    ssl_prefer_server_ciphers on;

    ssl_session_timeout 5m;

    ssl_session_cache shared:SSL:50m;

    gzip on;

    gzip_min_length 1k;

    gzip_buffers 4 16k;

    gzip_comp_level 2;

    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;

    gzip_vary off;

    gzip_disable "MSIE [1-6]\.";

    location /openim_rtc/ {

        proxy_http_version 1.1;

        proxy_set_header Upgrade $http_upgrade;

        proxy_set_header Connection "Upgrade";

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header Host $http_host;

        proxy_pass http://10.17.0.94:7880/;

    }

    location /openim_msg_gateway/ {

        proxy_http_version 1.1;

        proxy_set_header Upgrade $http_upgrade;

        proxy_set_header Connection "Upgrade";

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header Host $http_host;

        proxy_pass http://10.17.0.94:10001/;

    }

    location /openim_api/ {

        proxy_http_version 1.1;

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header Host $http_host;

        proxy_pass http://10.17.0.94:10002/;

    }

    location /openim_jssdk_gateway/ {

        proxy_http_version 1.1;

        proxy_set_header Upgrade $http_upgrade;

        proxy_set_header Connection "Upgrade";

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header Host $http_host;

        proxy_pass http://10.17.0.94:10003/;

    }

    location /openim_demo/ {

        proxy_http_version 1.1;

        proxy_set_header Upgrade $http_upgrade;

        proxy_set_header Connection "Upgrade";

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header Host $http_host;

        proxy_pass http://10.17.0.94:10004/;

    }

    location /openim_cms/ {

        proxy_http_version 1.1;

        proxy_set_header X-real-ip $remote_addr;

        proxy_set_header X-Forwarded-For $remote_addr;

        proxy_pass http://10.17.0.94:10006/;

    }

}

注意这里的各种各种斜杆的配置规则

3.3. minio配置

发送文件/图片/视频等选择minio

Minio需要单独转发

server {

    listen 783 ssl;

    server_name  localhost;

 

    ssl_certificate   /usr/local/openresty/nginx/cert/primary.pem;

    ssl_certificate_key  /usr/local/openresty/nginx/cert/key.pem;

    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    ssl_prefer_server_ciphers on;

    ssl_session_timeout 5m;

    ssl_session_cache shared:SSL:50m;

 

    gzip on;

    gzip_min_length 1k;

    gzip_buffers 4 16k;

    gzip_comp_level 2;

    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;

    gzip_vary off;

    gzip_disable "MSIE [1-6]\.”;

 

    location / {

        proxy_http_version 1.1;

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header Host $http_host;

        proxy_pass http://172.17.0.94:10005;

    }

}

注意,minio需要跟路径转发,不能设置任何path,不然会提示:

"GET /openim/?location= HTTP/1.1" 404 159 "-" "MinIO (ios; arm64) minio-go/v7.0.22" "-"

 

3.4. k8s service配置

apiVersion: v1
kind: Service
metadata:
  name: gateway
spec:
  type: NodePort
  externalTrafficPolicy: Local
  selector:
    app: gateway
  ports:- protocol: TCP
      port: 1773
      targetPort: 773
      nodePort: 1773
      name: openim-port
    - protocol: TCP
      port: 1783
      targetPort: 783
      nodePort: 1783
      name: minio-openim-port

opemim的pod的端口是773,service端口是1773

minio的pod的端口是783,service端口是1783

 

3.5. openim服务器修改

假设外网地址是www.test.com

唯一需要修改的地方是minio的地址:

credential: #腾讯cos,发送图片、视频、文件时需要,请自行申请后替换,必须修改
  minio: #MinIO 发送图片、视频、文件时需要,请自行申请后替换,必须修改。 客户端初始化InitSDK,中 object_storage参数为minio
    bucket: openim # 存储内容桶
    appBucket: app # 存储app的桶
    location: us-east-1
    endpoint: https://www.test.com:1783  #minio外网ip 这个ip是给客户端访问的
    endpointInner: http://127.0.0.1:10005 #minio内网地址 如果im server 可以通过内网访问到 minio就可以填写
    endpointInnerEnable: true #是否启用minio内网地址 启用可以让桶初始化,IM server连接minio走内网地址访问
    accessKeyID: user12345
    secretAccessKey: key12345

endpoint需要改成实际的外网地址

 

3.6. openim客户端修改

  // 初始化SDK

   IMController.shared.setup(

      apiAdrr: “https://www.test.com:1773/openim_api",

            wsAddr: “wss://www.test.com:1773/openim_msg_gateway/

  )

  Let API_BASE_URL = “https://www.test.com:1773/openim_demo”

 

 

  注意:openim_api和openim_demo它完整的url有其他参数,例如这样http://www.test.com:1773/openim_demo/demo/login,自己会带上斜杆。

但是这里wsaddr的地址必须要带上斜杆,因为它没有其他参数,所以不会自动添加斜杆,但是nginx配置那边是这样配置的:

location /openim_msg_gateway/ {

        proxy_http_version 1.1;

        proxy_set_header Upgrade $http_upgrade;

        proxy_set_header Connection "Upgrade";

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header Host $http_host;

        proxy_pass http://172.17.0.94:10001/;

    }  

 

至此就可以使用openim进行聊天了

posted @ 2022-07-27 17:45  若-飞  阅读(1798)  评论(9编辑  收藏  举报