teamtalk实现即时通讯

即时通讯技术应用非常广泛,涉及教育、电商、金融、泛娱乐、生活服务、医疗健康、政企服务、游戏聊天、在线客服等等行业,不是大家认为仅仅是qq、微信那样。

即时通讯架构

先给张图
teamtalk实现即时通讯_第1张图片
客户端与服务器端进行网络通信、收发消息连接层为客户端收发消息提供出入口。主要的任务:保持海量用户连接;解析协议,对传输内容进行编码;维护session;推送消息。
核心业务层负责IM系统各项功能的核心逻辑实现。
数据层负责IM系统相关数据的持久化存储,包括消息内容、账号信息等。

分层架构

teamtalk实现即时通讯_第2张图片
接入层的作用:连接整流、通信安全、报文解压缩、初步防攻击。一个接入层对应多个客户端。

逻辑层主要处理以下几个逻辑:

  • 用户逻辑:用户登录、用户退出、用户信息查询、用户更新签名、用户分组创建等
  • 好友逻辑:添加好友、删除好友、拉取好友列表、好友添加备注等
  • 群组逻辑:创建群、加入群、删除群、删除成员等
  • 消息逻辑:单聊文字消息、单聊语音消息、群聊文字消息、群聊语音消息、拉取离线消息等
  • 其他,比如文件传输、图片传输等

逻辑层的设计需要注意,要具备扩展性。
teamtalk实现即时通讯_第3张图片
可以水平扩展各个逻辑模块,也可以无缝添加新的逻辑服务,比如文件传输。负荷高的模块还可以再细分。

数据层功能:对上游屏蔽存储引擎、对上游屏蔽cache层、对上游提供友好接口。
注意数据层也要设计扩展性。

路由层功能:

  • 路由消息:消息投递
  • 内存存储:用户临时数据,比如用户状态信息(在线/离线)

这些模块通常都部署在同一个机房。

teamtalk

teamtalk实现即时通讯_第4张图片
teamtalk是用cpp实现的即时通讯组件,可以用作小型公司当作内部im办公交流。
简单介绍一下各个模块的功能:

  • Android/iOS/PC:各种客户端。
  • LoginServer: 主要负责负载均衡的作用,当收到客户端的请求时,分配一个负载最小的MsgServer给客户端。
  • MsgServer: TT的主要服务端,负责维护各个客户端的链接,消息转发等功能。
  • RouteServer: 负责消息路由的功能,当msg_server发现某个用户不在本服务器内,而又有消息需要发给他,就会将消息转发给route_server,route_server会将消息发给相应的msg_server,由此可知,route_server也维护了一定的用户状态。
  • DBProxy: 在TT中负责了主要的业务逻辑,主要与存储层打交道,提供mysql以及redis的访问服务,屏蔽其他服务器与mysql与redis的直接交互。
  • FileServer: 文件服务器,提供客户端之间得文件传输服务,支持在线以及离线文件传输
  • MsfsServer: 图片存储服务器,提供头像,图片传输中的图片存储服务。
  • PushServer: 负责Android、IOS客户端提醒消息的推送,类似微信的锁屏提醒消息。
  • Webserver:简单的管理功能。

以后还会详细介绍,这里先介绍怎么配置,先跑起来再说。

配置

这里介绍每一步应该干什么,还有踩过的坑。

安装常用组件

安装mysql、nginx、redis、php等常⽤组件。由于前三者之前已有介绍,这里不重复,只提示一下,记得先安装依赖。作为补充,介绍一下php的安装,以php7.2为例,7.4等版本注意修改版本号。
安装PHP7以及常⽤扩展

sudo apt-get -y install php7.2-fpm php7.2-mysql php7.2-common php7.2-mbstring php7.2-gd php7.2-json php7.2-cli php7.2-curl

启动php7.2-fpm进程

sudo systemctl start php7.2-fpm

查看php7.2-fpm运⾏状态

systemctl status php7.2-fpm
# 或者是
/etc/init.d/php7.2-fpm status

查看php版本号,测试php是否安装成功

php -v
# 或者是
php --version

修改php配置⽂件www.conf

sudo vim /etc/php/7.2/fpm/pool.d/www.conf

做如下操作

; 注释掉下两行(47 48行)
;listen.owner = www-data
;listen.group = www-data

; 将mode值修改为0666
listen.mode = 0666

重启php-fpm服务

sudo /etc/init.d/php7.2-fpm restart

编译teamtalk

找一版源码进行下载,地址就不贴了。
解压后进入tt目录,在/server/src目录下
下载编译protocol buffer库

sudo ./make_protobuf.sh

编译日志log4

sudo ./make_log4cxx.sh

聪明一点的会发现,以上两步其实还是准备工作,真正的编译是下面的

# 参数给的是自己定义的版本号
sudo ./build_ubuntu.sh version 1.0

以上三步的脚本就不贴了,可以结合这个安装过程一起看脚本。
编译完成后,会在/server目录下多了im-server-1.0.tar.gz压缩包,将im-server-1.0.tar.gz拷⻉到/auto_setup/im_server

cp im-server-1.0.tar.gz ../auto_setup/im_server/

修改配置

修改数据库配置

这里修改配置文件,使得配置文件中的密码与mysql密码一致,这里登录用的是root用户,如果用的不是mysql的root,进脚本修改。

cd auto_setup/mysql
vim setup.sh

修改后执行脚本,其实就是在mysql创建一系列表,也可以进conf里面看这个.sql文件到底干了什么。

sudo ./setup.sh install

执行完成后,会输出创建数据库成功的语句。
可以在mysql中查看

sudo mysql -u root -p
show databases;

可以看到数据库有teamtalk

配置各模块

这里介绍单机配置的过程。单机配置最为简单,先跑起来是王道,后期要改也容易。
主要是修改msgserver.conf、dbproxyserver.conf和loginserver.conf
先进入配置文件目录

cd auto_setup/im_server

各个模块的配置都在conf目录下。

修改msgserver.conf

vim conf/msgserver.conf

将FileServerIP改成FileServer所在的服务器的外⽹地址。

FileServerIP1=192.168.0.5
# 端口不要瞎改
FileServerPort1=8601

将28⾏的IpAddr1和IpAddr2改为本机IP外⽹地址

# msg_server本身的ip地址
IpAddr1=192.168.0.5 #电信IP
IpAddr2=192.168.0.5 #⽹通IP

如果配置多台机器,需要修改DBServerIP1、LoginServerIP1等地址。后面的配置就不强调这一点了。

修改dbproxyserver.conf

vim conf/dbproxyserver.conf

主要是修改配置文件里面的数据库用户和密码,注意主从两个库都要修改

teamtalk_master_username=root
teamtalk_master_password=123456

teamtalk_slave_username=root
teamtalk_slave_password=123456

修改loginserver.conf

vim conf/loginserver.conf

主要是修改msfs对应的ip

msfs=http://192.168.0.5:8700/

如果msfs的地址不对,则不能传输图⽚。

修改fileserver.conf

修改为外⽹ip地址,供客户端可以访问。注意ClientListenIp和MsgServerListenIp都要改成外网地址。

ClientListenIp=192.168.0.5
ClientListenPort=8600

MsgServerListenIp=192.168.0.5
MsgServerListenPort=8601

启动服务器

终于配置完了,运行脚本

sudo ./setup.sh install

看一下有没有启动成功

ps aux | grep _server
ps aux | grep msfs

如果大家都在,说明启动成功。但是不要高兴得太早,可能后面还有坑。
如果某个模块启动失败,可以单独重启某个服务模块

sudo auto_setup/im_server/im-server-1.0/restart.sh login_server

可以进⼊到/auto_setup/im_server/im-server-1.0⽬录中去看各个模块的日志,分析失败原因

tail -n 30 -f msg_server/log/default.log

部署web管理后台

回到项目最开始的目录,将php拷⻉⼀份为tt压缩后拷⻉到/auto_setup/im_web

# tt 这个名不要动
cp -ar php tt
zip -r tt.zip tt
cp tt.zip auto_setup/im_web/

修改web的配置⽂件

主要是ip地址和数据库⽤户名和密码以及nginx的配置。
进入到im_web目录

cd auto_setup/im_web

修改ip地址

vim conf/config.php

把ip地址修改为⾃⼰的外⽹地址

$config['msfs_url'] = 'http://192.168.221.130:8700/';
$config['http_url'] = 'http://192.168.221.130:8400';

修改数据库配置

vim conf/database.php

主要是修改用户名密码

$db['default']['username'] = 'root';
$db['default']['password'] = '123456';

配置nginx

# 这个名字有点迷惑性,其实就是nginx.conf来的
vim conf/im.com.conf

将server_name改为⾃⼰的ip地址,以及将php改成对应的版本号,这里是7.2

server
        {
                listen       80;
                server_name 0.0.0.0;  # 这里改成0.0.0.0了
                index index.html index.htm index.php default.html default.htm default.php;
                root         /var/www/html/tt;

                location ~ \.php($|/) {
                    fastcgi_pass   unix:run/php/php7.2-fpm.socket  # 对应版本号
                    fastcgi_index  index.php;
                    fastcgi_split_path_info ^(.+\.php)(.*)$;
                    fastcgi_param   PATH_INFO $fastcgi_path_info;
                    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                    include        fastcgi_params;
                }

                location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
                        {
                                expires      30d;
                        }

                location ~ .*\.(js|css)?$
                        {
                                expires      12h;
                        }
                if (!-e $request_filename) {
                    rewrite ^/(.*)$ /index.php/$1 last;
                    break;
                }
        }

使用浏览器查看,最好使⽤⾕歌浏览器(其他浏览器可能有兼容性问题)打开服务器的ip地址,然后登录,⽤户名和密码都为admin
teamtalk实现即时通讯_第5张图片
登录进去后则可以配置部⻔和成员,先配置部门,再配置成员,具体操作就略掉了。

客户端登录

终于都配好了,用客户端登录试一试。
windows端打开/win-client/bin/teamtalk/Release/teamtalk.exe
注意配置成⾃⼰msg_server的IP地址。
如果一切设置正常,这时就登录成功了,然后就可以使用即时通讯的各种功能。
当然,一般来说这个过程不会这么顺利,如果出现问题,先考虑是不是配置出了问题,尤其是ip地址的设置,此外还要多查看日志来分析。

docker部署

为了提高部署可移植性,可以把teamtalk各模块部署到docker上。这里就以login_server为例。

移植依赖文件

使用ldd,获取到所有依赖的动态库⽂件之后,将可执⾏⽂件、库⽂件⼀起打包即可移植到其他电脑运⾏,当然还需要指定程序运⾏时查找动态库的路径。(ubuntu系统下查找路径常为:/lib .usr/lib /usr/local/lib) 可以修改环境变量的⽅式将库⽂件路径加⼊到环境变量中,告诉系统在程序运⾏时到哪⾥去找依赖库,因此我们可以写一个运⾏脚本

# 使⽤脚本pack_lib.sh提取依赖⽂件
#!/bin/bash

function useage()
{
    cat << EOU
    Useage: bash $0 <path to the binary> <path to copy the dependencies>
    EOU
    exit 1
}

#Validate the inputs
[[ $# < 2 ]] && useage

#Check if the paths are vaild
[[ ! -e $1 ]] && echo "Not a vaild input $1" && exit 1
[[ -d $2 ]] || echo "No such directory $2 creating..."&& mkdir -p "$2"

#Get the library dependencies
echo "Collecting the shared library dependencies for $1..."
deps=$(ldd $1 | awk 'BEGIN{ORS=" "}$1\
~/^\//{print $1}$3~/^\//{print $3}'\
| sed 's/,$/\n/')
echo "Copying the dependencies to $2"

#Copy the deps
for dep in $deps
do
    echo "Copying $dep to $2"
    cp "$dep" "$2"
done
echo "Done!"

执行.sh即可把对应的so拷⻉到当前⽬录

# login_server要执行的文件
# . 依赖文件要拷贝到的目录
./pack_lib.sh login_server .

加装到docker内

编写Dockerfile

# This is dockerfile for login_server
# base image
FROM ubuntu:16.04  # 这个login_server是在ubuntu16.04上编译的
# author
MAINTAINER s
CMD "mkdir /home/login_server"
# 添加到home⽬录
COPY ./login_server /home/login_server
EXPOSE 8008
EXPOSE 8080
EXPOSE 8100
WORKDIR "/home/login_server"
CMD ["./login_server"]

制作镜像

docker build -t login_server .

查看镜像

docker image ls

如果制作成功会有记录。

启动和映射端⼝

内部端⼝是固定的,我们启动docker的时候可以重新做映射。

docker run -d -p 8008:8008 -p 8080:8080 -p 8100:8100 login_server

这样就能运行成功了,可以通过docker ps -all查看运行起来的容器,也可以直接ps aux | grep file_server查看。

传入参数

扩展一下,如果要用docker启动多个login_server,这里由于配置的ip和port都是写死了的,那就不能启动多个镜像。这里需要传入ip等参数。
Dockerfile要改一下

ENV HOST=""
ENV PORT=""
ENV NAME=""
ENV PWSSD=""
ENV KEY=""
CMD ["./login_server $HOST"]

启动时通过-e传入参数

docker run -d -p 8008:8008 -p 8080:8080 -p 8100:8100 -e HOST="192.168.0.5" login_server

特别要注意login_server源码也要修改,要让ip等参数接到argv[]的值。

你可能感兴趣的:(笔记,后端,docker)