HC開源物管系統部署-docker部署的那些坑

零、前言

發文的時候突然發現受邀可以開通付費功能了,下篇文章開個1塊錢的付費文章看看效果。

正文:

最近在弄一個開源的物業系統,感謝java110團隊的開源,感謝吳學文同學對我不厭其煩的部署問題的包容。

發現用docker部署springcloud系統,真是坑太多了。

前端頁面


功能架構:

小程序:

技術棧:

中間件:mysql5.6、zookeeper、Redis和kafka

後端框架:spring cloud + eureka

服務列表:

一、    部署說明

1、    軟硬件配置

硬件:雲服務器最低配置4核16G

軟件:需要安裝 mysql + kafka + zookeeper + redis,docker可選

開源代碼說明:

HC小區後端代碼

https://gitee.com/wuxw7/MicroCommunity

HC小區前段代碼

https://gitee.com/java110/MicrCommunityWeb

HC智慧家庭(業主版)

https://gitee.com/java110/WechatOwnerService

HC掌上物業(物業版)

https://gitee.com/java110/PropertyApp

分支說明(branch):

分支管理說明,master 爲前後端未分離代碼,back 爲前後端分離後端代碼

2、    新建賬號

添加hc、 mysql、 redis、 zk 、kafka 用戶

# 應用賬戶,安裝docker,運行jar包
sudo adduser hc 

# 數據庫
sudo adduser mysql 

sudo adduser redis 
sudo adduser zk
sudo adduser kafka

修改密碼

passwd hc

密碼應符合大小寫英文字母+特殊符號+數字,最短8位較好

Changing password for user hc.
New password: 

如 Yao@5937。

3、接下來賦予sudo權限,輸入命令

sudo visudo

此命令意思是vim /etc/sudoers,但是會有sudo的校驗,所以推薦上面的用法。

在文件中,找到下面這段,在root下添加上面添加的5個用戶

## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL

添加完後,如下

## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL
hc      ALL=(ALL)       ALL
mysql   ALL=(ALL)       ALL
redis   ALL=(ALL)       ALL
zk      ALL=(ALL)       ALL
kafka   ALL=(ALL)       ALL

:wq 保存退出。

二、    安裝docker

1、切換hc用戶,登錄服務器

2、安裝docker

sudo yum install docker -y

查看docker版本

docker version

疑問:

看docker的安裝文章都是用yum install docker-ce 安裝的,是因爲ce是免費版。
但是當前時間2020/03/19,這個命令已經無法安裝。

那用 yum install docker -y 命令是安裝的 CE 還是 EE 版本?

我的版本

[root@hostone /]# docker version
Client:
 Version:         1.13.1
 API version:     1.26
 Package version: 
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

有句奇怪的話,問你docker咋沒運行?別急,啓動下

sudo systemctl start docker  #啓動docker
sudo systemctl enable docker #開機啓動docker
sudo systemctl status docker #查看docker狀態

再用docker version 看下

[root@hostone /]# docker version
Client:
 Version:         1.13.1
 API version:     1.26
 Package version: docker-1.13.1-109.gitcccb291.el7.centos.x86_64
 Go version:      go1.10.3
 Git commit:      cccb291/1.13.1
 Built:           Tue Mar  3 17:21:24 2020
 OS/Arch:         linux/amd64

Server:
 Version:         1.13.1
 API version:     1.26 (minimum version 1.12)
 Package version: docker-1.13.1-109.gitcccb291.el7.centos.x86_64
 Go version:      go1.10.3
 Git commit:      cccb291/1.13.1
 Built:           Tue Mar  3 17:21:24 2020
 OS/Arch:         linux/amd64
 Experimental:    false

ok,很簡單地安裝完成了。

最後,創建docker用戶組,賦權給hc用戶

sudo groupadd docker

sudo usermod -aG docker hc

切換到hc賬戶,查看docker狀態

sudo docker ps

然後需要安裝一個docker-comose,來啓動,停止和重啓應用

sudo yum install docker-compose

docker啓動、停止命令

# 啓動
sudo systemctl start docker

# 守護進程重啓
sudo systemctl daemon-reload

# 重啓docker服務
sudo systemctl restart docker

# 重啓docker服務
sudo service docker restart

# 關閉docker  
sudo systemctl stop docker

三、安裝mysql

1、新開個mysql連接窗口,切換到mysql 用戶。

2、下載安裝mysql

# 下載5.7 安裝包
wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm

# 配置安裝依賴
sudo yum localinstall -y mysql57-community-release-el7-8.noarch.rpm

# 安裝數據庫
sudo yum install -y mysql-community-server

# 數據庫啓動
sudo systemctl start mysqld

# 查看數據庫狀態
systemctl status mysqld

# 數據庫啓動
sudo systemctl enable mysqld

3、安裝啓動完成,查看密碼

# 密碼在mysql日誌中
grep 'pass' /var/log/mysqld.log 

[mysql@iZ2zebthf35ejlps5v87ksZ ~]$ grep 'pass' /var/log/mysqld.log 
2020-03-14T12:28:57.0512181 [Note] A temporary password is generated for root@localhost: <z?Shbek>8Gd


4、連接mysql

# 連接mysql, 默認端口3306
mysql -u root -p

輸入密碼

SET PASSWORD = PASSWORD('Db@369012');

mysql> SET PASSWORD = PASSWORD('Db@369012');
Query OK, 0 rows affected, 1 warning (0.00 sec)

5、創建hc用戶,賦權

create user 'TT'@'%' identified by 'TT@HCvvMM33';
create user 'hc_community'@'%' identified by 'hc_community@HCvvMM33';
flush privileges;
CREATE DATABASE `TT` ;
grant all privileges on `TT`.* to 'TT'@'%' ;
CREATE DATABASE `hc_community` ;
grant all privileges on `hc_community`.* to 'hc_community'@'%' ;
flush privileges;

6、啓動配置

如果是5.7版本的mysql,導入時可能報錯,需要修改my.cnf

sudo vim /etc/my.cnf

修改內容如下,在[mysqld]下添加

# 導入大SQL文件
max_allowed_packet=900

# 解決5.6的SQL在5.7的執行錯誤 ERROR 1067 (42000) Invalid default value for 'end_time'
sql_mode = ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

修改完後,重啓mysql

sudo systemctl restart mysqld

systemctl status mysqld

7、導入最新的sql文件

連接TT用戶,導入前後端分離版的SQL,文件名

分離版2020.3.18.sql

連接hc_community,導入SQL文件

hc_community20200220.sql

四、安裝java

1、切回hc用戶登陸服務器

su - hc

2、上傳java至/home/hc

# 創建java文件夾
sudo mkdir –p /usr/local/java

# 解壓至/usr/local/java
sudo tar zxvf jdk-8u131-linux-x64.tar.gz -C /usr/local/java

3、配置java環境

打開系統配置文件

sudo vim /etc/profile

在文件最後添加內容如下:

export JAVA_HOME=/usr/local/java/jdk1.8.0_131 
export JRE_HOME=$JAVA_HOME/jre 
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH 
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

記得刷新變量環境

# 刷新變量環境
source /etc/profile

查看是否生效

[hc@iZ2zebthf35ejlps5v87ksZ java]$ echo $JAVA_HOME 
/usr/local/java/jdk1.8.0_131

五、安裝redis

1、切換爲redis用戶,上傳源碼包至/home/redis

# 查看當前路徑
[redis@iZ2zebthf35ejlps5v87ksZ ~]$ pwd
/home/redis

# 查看當前路徑下文件
[redis@iZ2zebthf35ejlps5v87ksZ ~]$ ll
total 1684
-rw-rw-r-- 1 redis redis 1723533 Mar 14 21:03 redis-4.0.6.tar.gz

2、解壓

tar zxvf redis-4.0.6.tar.gz

文件解壓後,有個文件夾redis-4.0.6,如下:

[redis@iZ2zebthf35ejlps5v87ksZ ~]$ ll
total 1688
drwxrwxr-x 6 redis redis    4096 Dec  5  2017 redis-4.0.6
-rw-rw-r-- 1 redis redis 1723533 Mar 14 21:03 redis-4.0.6.tar.gz

3、編譯安裝

cd redis-4.0.6

sudo make prefix=/home/redis/redis-4.0.6 install

如果不用sudo,安裝失敗,信息如下

Hint: It's a good idea to run 'make test' ;)

INSTALL install
install: cannot create regular file ‘/usr/local/bin/redis-server’: Permission denied
make[1]: *** [installError 1
make[1]: Leaving directory `/home/redis/redis-4.0.6/src'
make: *** [install] Error 2

成功安裝

make[1]: Entering directory `/home/redis/redis-4.0.6/src'
CC Makefile.dep
make[1]: Leaving directory `/home/redis/redis-4.0.6/src'
make[1]: Entering directory `/home/redis/redis-4.0.6/src'

Hint: It's a good idea to run 'make test' ;)

    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
make[1]: Leaving directory `/home/redis/redis-4.0.6/src'

4、redis配置修改

備份reids.conf

cp redis.conf redis.conf_hc

# 修改redis配置
vim redis.conf

修改內容如下

# 任何機器都可以訪問,生產環境需改成特點ip訪問
bind 0.0.0.0

# 密碼
requirepass hc8866

# 守護進程
daemonize yes

:wq 保存退出。

5、啓動redis

./src/redis-server ./redis.conf

啓動信息如下

[redis@iZ2zebthf35ejlps5v87ksZ redis-4.0.6]$ ./src/redis-server ./redis.conf
9490:C 14 Mar 22:45:12.384 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
9490:C 14 Mar 22:45:12.384 # Redis version=4.0.6, bits=64, commit=00000000, modified=0, pid=9490, just started
9490:C 14 Mar 22:45:12.384 # Configuration loaded

6、客戶端連接redis

./src/redis-cli -p 6379 -a hc8866

連接成功內容如下

[redis@izbp117mtgmllet9ryobawz redis-4.0.6]$ ./src/redis-cli -p 6379 -a hc8866
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> 

推薦使用rdm等客戶端工具查看redis數據。

六、安裝zookeeper

1、切換爲zk用戶,上傳源碼包至/home/zk

2、解壓

tar zxvf zookeeper-3.4.6.tar.gz 

3、進入zk目錄

 cd zookeeper-3.4.6

4、準備啓動conf

cp ./conf/zoo_sample.cfg ./conf/zoo.cfg

5、啓動zk

./bin/zkServer.sh start

啓動信息如下

[zk@iZ2zebthf35ejlps5v87ksZ zookeeper-3.4.6]$ ./bin/zkServer.sh start
JMX enabled by default
Using config: /home/zk/zookeeper-3.4.6/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

七、部署項目

1、切迴應用賬戶hc,安裝git

sudo yum install git -y

2、安裝maven

sudo yum install maven -y

3、修改maven源爲阿里源

sudo vim /usr/share/maven/conf/settings.xml 

在mirrors標籤下添加如下內容

<mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>
 </mirror>

4、下載代碼

mkdir hcProject

cd hcProject

git clone https://gitee.com/wuxw7/MicroCommunity.git

5、編譯代碼

cd /home/hc/hcProject/MicroCommunity

mvn clean install

6、修改redis配置

打開hcConf項目下所有 application-dev.yml,修改redis賬號密碼

端口沒有修改則不用更換

7、替換ip

打開所有docker-compose.yml,如hcConf\Api\docker\docker-compose.yml

這裏推薦在windows下用nodePad++的文件查找替換功能,在目錄下批量替換

如果喜歡在Linux修改的話,可以用sed 批量替換

將如下內容中的ip替換爲對應的服務器ip

   extra_hosts:
   - "dev.java110.com:192.168.100.29"
   - "dev.db.java110.com:192.168.100.29"
   - "dev.zk.java110.com:192.168.100.29"
   - "dev.kafka.java110.com:192.168.100.29"
   - "dev.redis.java110.com:192.168.100.29"
   - "api.java110.com:192.168.100.29"

8、上傳bin 和 hcConf 至目錄/home/hc/hcProject 下

八、後端docker服務啓動

1、下載修改後的yaoHcConf文件,解壓後得到bin、hcConf目錄,上傳至hcProject

2、啓動reset_all.sh

相比羣裏的原文件,增加了FrontService與eureka的服務。

吳老大說沒必要每次都重啓eureka服務,想想對於初次接觸HC項目的小白們(比如我)來說,還是比價有難度的,所以把eureka加進去了,省事。

cd /home/hc/hcProject/bin

chmod +x *.sh

sudo ./reset_all.sh

3、docker 常用命令

啓動後查看服務是否啓動成功

# 查看所有正在運行容器
sudo docker ps 

# containerId 是容器的ID
sudo docker stop containerId 

 # 查看所有容器
sudo docker ps -a

# 查看所有容器ID
sudo docker ps -a -q 

# stop停止所有容器
sudo docker stop $(sudo docker ps -a -q) 
sudo docker stop $(sudo docker ps -aq)

# remove刪除所有容器
sudo docker  rm $(sudo docker ps -a -q)  

# 刪除所有鏡像
sudo docker rmi $(sudo docker images -q)

# 進入某個容器查看
sudo docker exec -i -t [containerId] /bin/bash
# 示例
sudo docker exec -it [76ae97d878eb] /bin/bash

4、異常處理

  • 1) network 異常

異常:

ERROR: Network java110-net declared as external, but could not be found. Please create the network manually using docker network create java110-net and try again.

解決方法:

docker network create java110-net
  • 2)特殊字符問題

docker中容器未啓動成功

CONTAINER ID        IMAGE                             COMMAND                  CREATED             STATUS                         PORTS                    NAMES
6632de00214f        docker_frontserivce               "/root/start_front..."   30 minutes ago      Restarting (12 minutes ago                            frontserivce-1

使用docker logs 查看日誌

sudo docker logs -f --tail=100 76ae97d878eb

報錯如下

standard_init_linux.go:178: exec user process caused "no such file or directory"

先停止了這個服務,然後去服務下(/home/hc/hcProject/app/FrontService)看看是什麼問題,懷疑是啓動腳本問題

sudo docker-compose -f /home/hc/hcProject/app/FrontService/docker/docker-compose.yml       down;

發現是frontserivce的docker下的onStart.sh、start_front.sh腳本中出現了^M字符,使用dos2unix工具轉換下。

cd /home/hc/hcProject/app/FrontService/docker

sudo yum install dos2unix

sudo dos2unix onStart.sh

sudo dos2unix ./bin/start_front.sh

啓動這個服務

sudo docker-compose -f /home/hc/hcProject/app/FrontService/docker/docker-compose.yml       up -d --build --force-recreate;

如果沒有down掉服務,也可使用重啓命令

sudo docker-compose -f /home/hc/hcProject/app/FrontService/docker/docker-compose.yml       restart;

在使用restart的腳本重啓後發現又出現報錯了,突然想到是源頭腳本出了問題,restart的腳本又copy了一次hcConf下文件。

看了下果然如此,重新去除下特殊字符^M

vi -b /home/hc/hcProject/hcConf/FrontService/docker/onStart.sh

sudo dos2unix /home/hc/hcProject/hcConf/FrontService/docker/*.sh

cd /home/hc/hcProject/bin   

sudo ./restart_all.sh
  • 3) yml 格式問題

啓動之後又發現問題

2020-03-19 18:29:24.945 ERROR 8 --- [           main] o.s.boot.SpringApplication               : Application run failed
java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application-dev.yml'
……
could not find expected ':' in 'reader', line 15column 1:
eureka:    ^
at org.yaml.snakeyaml.scanner.ScannerImpl.stalePossibleSimpleKeys(ScannerImpl.java:466)   

明顯提示第15行的yml文件報錯,查看了下,報錯原文如下

password:hc8866

是因爲password第冒號後沒有空一格輸入密碼。

  • 4) hosts問題

命運多舛,又出了問題

DiscoveryClient_FRONT-SERVICE/172.19.0.3:8012: registering service...

這次的問題是因爲docker-compose.yml, 因爲新版的前後端分離版本升級第關係,羣文件的hcConf裏沒有FrontService,我從MicroCommunity拷貝了一個過去,但是沒有啓用extra_hosts,還是用第net_works導致。原文件片段如下:

version: '2'
services:
   frontserivce:
       container_name: frontserivce-1
       build:
          context: .
          dockerfile: Dockerfile
       restart: always
       ports:
       - "8020:8020"
       volumes:
       - ../target/FrontService.jar:/root/target/FrontService.jar
       networks:
       - java110-net
#       mem_limit: 1024m
#       extra_hosts:
#       - "dev.java110.com:192.168.1.18"
#       - "dev.db.java110.com:192.168.1.18"
#       - "dev.zk.java110.com:192.168.1.18"
#       - "dev.kafka.java110.com:192.168.1.18"
#       - "dev.redis.java110.com:192.168.1.18"
#       - "api.java110.com:92.168.1.18"
networks:
  java110-net:
    external: true

修改後如下

version: '2'
services:
   frontserivce:
       container_name: frontserivce-1
       build:
          context: .
          dockerfile: Dockerfile
       restart: always
       ports:
       - "8020:8020"
       volumes:
       - ../target/FrontService.jar:/root/target/FrontService.jar

       mem_limit: 1536m
       extra_hosts:
       - "dev.java110.com:47.96.141.41"
       - "dev.db.java110.com:47.96.141.41"
       - "dev.zk.java110.com:47.96.141.41"
       - "dev.kafka.java110.com:47.96.141.41"
       - "dev.redis.java110.com:47.96.141.41"
       - "api.java110.com:47.96.141.41"

47.96.141.41爲docker服務器宿主機地址。

  • 5) docker啓動腳本問題

發現docker的8012端口啓動了,但是其實真正的服務沒有啓動,log也沒有報錯,停留在

2020-03-20 14:22:55.501  INFO 1317 --- [ost-startStop-1] c.netflix.config.DynamicPropertyFactory  : DynamicPropertyFactory is initialized with configuration sourcescom.netflix.config.ConcurrentCompositeConfiguration@616da524

進入docker內部的bash看看

sudo docker exec -it frontserivce-1 /bin/bash

進入bash後,查看進程

ps -aux

發現並沒有java -jar進程,在docker容器內手動啓動下試試

java -jar -Dspring.profiles.active=dev -Xms512m -Xmx1024m target/FrontService.jar

竟然啓動起來了,啓動後內容如下

root@9018e70e1220:~# ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  21108  1508 ?        Ss   14:28   0:00 /bin/bash /root/start_front.sh dev
root         8  0.0  0.0   7456   632 ?        S    14:28   0:00 tail -100f front.log
root        38  0.0  0.0  21324  2148 ?        Ss   14:36   0:00 /bin/bash
root        66  9.4  4.5 4757012 733244 ?      Sl+  14:41   1:14 java -jar -Dspring.profiles.active=dev -Xms512m -Xmx1024m target/FrontService.jar

估計還是啓動腳本有問題,需要回頭排查下。

九、前端服務部署

1、down下來前端項目

git clone  https://gitee.com/java110/MicrCommunityWeb.git

2、安裝nodeJs環境

3、打開項目,修改app.js

app.use('/callComponent',proxy('http://後端服務ip:8012',opts));

修改ip端口爲FrontService的服務端口

4、啓動

與app.js統計目錄下,輸入命令編譯啓動

npm install

npm start

打開ip:3000端口,查看前端頁面

端口可以修改,在項目的 bin/www 文件中

var port = normalizePort(process.env.PORT || '3000');

十、後記

部署HC項目可謂一波三折,先是自己的阿里雲上部署,到啓動的時候發現資源不夠,2H4g的機器完全帶不動。

讓公司申請了個4核16G的機器,花了兩天時間,踏了很多坑,終於搞定。

其中,坑最多的就是在windows上批量替換導致的特殊字符^M的問題。

在這次部署的過程中,收穫最大的應該就是對docker的使用了。

不過這次部署還沒發現docker的好處,坑倒是挺多,後續的日子裏繼續打打交道吧。

本文分享自微信公衆號 - 架構師之殤(ysistrue)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

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