goim編譯——bilibili開源聊天室,支持百萬用戶在線

goim簡介

官網:https://goim.io/
goim是bilibili公司技術總監毛劍創作,使用go語言開發,用於B站生產線上的IM服務框架(聊天室),其框架原理圖如下:
在這裏插入圖片描述
部署成功後的websocket的demo如下:
在這裏插入圖片描述

基礎環境

golang環境

1.下載二進制包:go1.4.linux-amd64.tar.gz

wget https://dl.google.com/go/go1.14.3.linux-amd64.tar.gz

2.將下載的二進制包解壓至 /usr/local目錄

tar -C /usr/local -xzf go1.14.3.linux-amd64.tar.gz

3.配置go環境變量

$ vim ~/.bash_profile
# 將以下環境變量添加到profile最後面
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
export GOPATH=/home/go              // 存放go源碼的目錄
$ source ~/.bash_profile // 生效
$ go env // 查看是否成功

java

1.下載:https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html

$ mkdir -p /usr/local/java
$ tar -zxvf jdk-8u241-linux-x64.tar.gz -C /usr/local/java/ # 解壓

2.環境變量配置

$vim ~/.bash_profile

# 加入到末尾
export JAVA_HOME=/usr/local/java/jdk1.8.0_141
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

$ source ~/.bash_profile
$ java -verison

kafka

具體見:http://kafka.apache.org/quickstart

1.下載安裝

cd /data
wget https://mirror.bit.edu.cn/apache/kafka/2.5.0/kafka_2.12-2.5.0.tgz
tar -zxvf kafka_2.12-2.5.0.tgz
cd kafka_2.12-2.5.0

2.啓動ZooKeeper

bin/zookeeper-server-start.sh config/zookeeper.properties

3.啓動kafka

bin/kafka-server-start.sh config/server.properties

4.後臺啓動
上面2和3執行後,終端退出服務就停止了,加&變成後臺運行,使用nohup把輸出重定向到另外一個文件

nohup sh bin/zookeeper-server-start.sh config/zookeeper.properties >>zookeeper.out &
nohup sh bin/kafka-server-start.sh config/server.properties >>kafka.out &

restart_kafka.sh如下

#!/bin/sh
# 停止
stop(){
  ./kafka-server-stop.sh
}

# 啓動
start(){
  nohup sh bin/kafka-server-start.sh config/server.properties >>kafka.out &
}

stop
start

5.測試,創建一個topic

bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic test

6.查看已創建的topic

bin/kafka-topics.sh --list --bootstrap-server localhost:9092

上面都OK,恭喜你,單機版的kafka安裝啓動成功!

針對goim需要的一些配置:
1.創建goim-push-topic(job會用到)

bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic goim-push-topic

2.更改監聽IP地址

vim config/server.properties
# 把下面一行取消註釋,並且輸入部署kafka機器的IP地址
#listeners=PLAINTEXT://:9092
listeners=PLAINTEXT://10.0.107.218:9092

redis

1.安裝啓動

yum install redis
systemctl restart redis # 啓動redis

2.更改配置文件

vim /etc/redis.conf
bind 127.0.0.1 -> bind 10.0.107.218
systemctl restart redis # 啓動redis

3.可選【安裝mac redis可視化工具 rdm】
點擊connect to redis server,輸入host。然後點擊Test Connection,提示成功後點擊OK即可。

編譯

編譯goim

參考:https://goim.io/tutorials/

cd $GOPATH/src  // 上面的/home/go,也可以使用echo $GOPATH查看具體路徑
mkdir -p github.com/Terry-Mao/
cd github.com/Terry-Mao/
git clone https://github.com/Terry-Mao/goim.git
cd goim

make build

報錯:

go: github.com/BurntSushi/[email protected]: Get "https://proxy.golang.org/github.com/%21burnt%21sushi/toml/@v/v0.3.1.mod": dial tcp 34.64.4.113:443: i/o timeout

所下載的庫依賴有官方庫,而官方被封禁網導致,設置代理:

// go env裏面永久多了一項:GOPROXY="https://goproxy.cn"
go env -w GOPROXY=https://goproxy.cn 
// 重新編譯
make build

成功後,生成target目錄,包含下面的文件:

[root@localhost goim]# ls target/
comet  comet.toml  job  job.toml  logic  logic.toml

PS:他們都依賴7171端口的discovery服務,這個是出自bilibili的一個類似zookeeper的服務註冊與發現的模塊,見下面。

編譯Discovery

具體見:https://github.com/bilibili/discovery

PS1:go1.12以上版本
PS2:該開源項目參考了spring cloud裏面服務發現的Netflix Eureka(https://github.com/Netflix/eureka)模塊設計。
PS3:本質上也是認爲ZK難用好,複雜而自研的服務註冊與發現框架。

cd $GOPATH/src
git clone https://github.com/bilibili/discovery.git
cd discovery/cmd/discovery
go build

cp discovery 

3.編譯goim的websocket-server,這是自帶測試的客戶端,使用了gin框架。

cd $GOPATH/src/github.com/Terry-Mao/goim/examples/javascript
go build -o httpd-ws

安裝

1.新增data目錄

cd /
mkdir -p /data/goim

2.拷貝goim(包括comet、logic、job和3個配置文件)

cp -r $GOPATH/src/github.com/Terry-Mao/goim/target /data/goim/

3.拷貝goim-websocket的example服務端

cp -rf $GOPATH/src/github.com/Terry-Mao/goim/examples /data/goim/

4.拷貝discovery

cp $GOPATH/src/discovery/cmd/discovery/discovery /data/goim/target/
cp $GOPATH/src/discovery/cmd/discovery/discovery-example.toml /data/goim/target/
cd /data/goim/
ls 

現在/data/goim應該是這樣的

[root@localhost goim]# ls
examples  target
[root@localhost goim]# ls target/
comet  comet.toml  discovery  discovery.toml  job  job.toml  logic  logic.toml
[root@localhost goim]# ls examples/
cert.pem  javascript  private.pem

下面簡述一下如何修改配置文件,和增加restart.sh和stop.sh,一鍵啓動和停止。

部署

假設本機IP爲:10.0.107.218,kafka\redis\discovery\goim\examples都部署在1臺機器上。

注意:爲何不建議是127.0.0.1?主要爲了方便調試源碼。

1.kafka檢查IP並重啓

vim /data/kafka_2.12-2.5.0/config/server.properties
listeners=PLAINTEXT://10.0.107.218:9092

2.redis檢查IP

vim /etc/redis.conf
bind 10.0.107.218

3.關閉防火牆

systemctl stop firewalld # 注意如果重啓防火牆會自動打開,可以永久禁用掉systemctl disable firewalld

4.discovery-example.toml(注意,不能改成discovery.toml,否則會出錯)

cd /data/goim/target && vim discovery-example.toml
nodes = ["10.0.107.218:7171"]
addr = "10.0.107.218:7171"

5.comet.toml

vim comet.toml
nodes = ["10.0.107.218:7171"] # discovery的地址
certFile = "examples/cert.pem" # wss協議ssl證書
privateFile = "examples/private.pem" # ssl私鑰
WhiteLog  = "log/white_list.log" # 統一存放到/data/goim/log目錄下

PS:example裏面的websocket客戶端就是連接的logic的3102端口。

6.job.toml

vim job.toml
: # 輸入一個:號,進入替換模式
%s/127.0.0.1/10.0.107.218/g

7.logic.toml

vim logic.toml
: # 輸入一個:號,進入替換模式
%s/127.0.0.1/10.0.107.218/g

PS:發消息使用postman測試是的WEB API是logic提供的。

8.examples

vim /data/goim/examples/javascript/client.js
//var ws = new WebSocket('ws://sh.tony.wiki:3102/sub');
var ws = new WebSocket('ws://10.0.107.218:3102/sub');

9.創建log目錄

mkdir -p /data/goim/log
mkdir -p /data/goim/log/comet
mkdir -p /data/goim/log/discovery
mkdir -p /data/goim/log/job
mkdir -p /data/goim/log/logic
cd /data/goim/log && vim white_list.log # 創建一個空文件

10.stop.sh

#!/bin/sh

stop(){
  pkill -f target/logic
  pkill -f target/job
  pkill -f target/comet
  pkill -f target/discovery
}

stop

11.restart.sh

nohup:終端退出時,可以服務運行
&:後臺運行,但是如果只有這個命令,終端退出後進程終止。
-> log/discovery.log:把nohub捕獲的輸出寫入到文件中
-log.dir=“log/discovery”:glog庫,輸出日誌文件的目錄。不設置則不會有日誌
-stderrthreshold=INFO:glog庫,輸出日誌到控制檯。
注意:glog是基於性能考慮,每隔一段時間(10秒?)纔會刷一次log(寫入文件和控制檯)

#!/bin/sh
stop(){
  pkill -f target/logic
  pkill -f target/job
  pkill -f target/comet
  pkill -f target/discovery
}

startDiscovery(){
  echo 'start discovery'
  nohup target/discovery -conf=target/discovery-example.toml -log.dir="log/discovery" > log/discovery.log &
}

startHttpWsServer(){
  echo 'start websocket server'
  nohup examples/javascript/httpd-ws > log/httpd-ws.log &
}

startGoim(){
  echo 'start logic server'
  nohup target/logic -conf=target/logic.toml -region=sh -zone=sh001 -deploy.env=dev -weight=10 -log_dir="log/logic" -stderrthreshold=INFO 2>&1 > log/logic.log &
  sleep 1

  echo 'start comet server'
  nohup target/comet -conf=target/comet.toml -region=sh -zone=sh001 -deploy.env=dev -weight=10 -addrs=10.0.107.218 -debug=true -log_dir="log/comet" -stderrthreshold=INFO 2>&1 > log/comet.log &
  sleep 1

  echo 'start job server'
  nohup target/job -conf=target/job.toml -region=sh -zone=sh001 -deploy.env=dev -log_dir="log/job" -stderrthreshold=INFO 2>&1 > log/job.log &
}

show(){
  sleep 1
  ps aux|grep target
}

stop
startDiscovery
startHttpWsServer
sleep 2
startGoim
show

運行

1.確保kafka和redis已啓動。具體見上面
2.啓動

cd /data/goim/ && chmod 777 *.sh
./restart.sh

3.查看

ps aux|grep target

4.日誌

tail -f log/comet.log       # 看這個
tail -f log/logic.log       # 和這個多一點
tail -f log/discovery.log
tail -f log/job.log

測試

1.瀏覽器訪問:http://10.0.107.218:1999/
在這裏插入圖片描述

2.點擊examples/javascript
在這裏插入圖片描述

3.使用postman向聊天室發一條消息
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章