全棧式部署:SpringCloud 微服務+Docker + Vue + nginx 先後端一站式部署

本文將帶你們從一臺全新的 CentOS 服務器開始,部署一套完整的先後端分離項目。操做步驟很是詳細,新手友好型文章~html

後端技術棧:SpringCloud 微服務架構 + Redis + RabbitMQ + MySql;前端

前端技術棧:Vue + ElementUI;java

部署工具:後端用 Docker 容器化部署,並把命令封裝成腳本自動執行;前端用 Nginx 作代理。node

1、前期準備

系統版本爲:CentOS 7.6 64位。mysql

1.1 鏈接服務器

要對遠程服務器進行操做,首先要連上服務器才行。打開命令行工具,輸入如下命令,再輸入服務器實例的密碼,便可遠程鏈接到服務器。linux

ssh root@xxx.xx.xx.xx
複製代碼

@ 以後是服務器的公網 ip,假如服務器 ip 地址爲:120.456.78.123,那麼鏈接服務器的命令爲:nginx

ssh root@120.456.78.123
複製代碼

敲回車以後會讓輸入密碼,輸入正確的密碼便可。c++

1.2 安裝 Docker

Docker 容器化部署的優勢就很少說了,直接上乾貨如何安裝 Docker。redis

下面直接把代碼框裏的命令拷貝到命令行執行就能夠。spring

先移除舊版本(若是有):

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine
複製代碼

安裝一些必要的工具:

sudo yum install -y yum-utils device-mapper-persistent-data lvm2
複製代碼

添加軟件源信息:

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
複製代碼

更新 yum 緩存:

sudo yum makecache fast
複製代碼

安裝 Docker-ce:

sudo yum -y install docker-ce
複製代碼

啓動 Docker 後臺服務

sudo systemctl start docker
複製代碼

測試運行 hello-world(這步可要可不要,目的是驗證身份安裝 Docker 成功,若是成功會打印出 Hello World)

docker run hello-world
複製代碼

1.3 安裝 mysql

拉取 mysql5.7 版本的鏡像

docker pull mysql:5.7
複製代碼

運行 MySql

docker run -p 3306:3306 --name mysql -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
複製代碼

命令說明:

  • -p 3306:3306:將容器的 3306 端口映射到主機的 3306 端口。
  • -v $PWD/conf:/etc/mysql/conf.d:將主機當前目錄下的 conf/my.cnf 掛載到容器的 /etc/mysql/my.cnf。
  • -v $PWD/logs:/logs:將主機當前目錄下的 logs 目錄掛載到容器的 /logs。
  • -v $PWD/data:/var/lib/mysql :將主機當前目錄下的data目錄掛載到容器的 /var/lib/mysql 。
  • **-e MYSQL_ROOT_PASSWORD=123456:**初始化 root 用戶的密碼。

注意在運行以前切換到合適的目錄,由於 MySql 容器映射到本機的目錄是映射的當前目錄的相對目錄。好比當前目錄爲 /root/abc ,那執行完上面的命令後,會在 /root/abc 下建立 MySql 掛載出來的目錄和文件。

1.4 安裝 redis

也能夠直接執行運行命令,若是系統檢測到沒有安裝此鏡像,則會拉取安裝,再運行。

下載並運行 redis:4.0.8 :

docker run -p 6379:6379 -t -dit redis:4.0.8
複製代碼

1.5 安裝 RabbitMQ

跟上面同樣也是直接執行運行命令安裝並運行 rabbitmq:3.7.7

docker run -d --hostname my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.7.7-management
複製代碼

到此部署微服務後端項目的前期環境準備工具已經作完。若是要部署前端還須要安裝 Nginx,這個在前端部署的章節再講。

2、後端部署

部署後端須要作的工做有兩個,一個是修改每一個微服務模塊的配置文件 application.yml ,另外一個是編寫 Dockerfile

先看目錄結構:

一共有 5 個模塊,其中 common 是純 java 代碼用於各模塊公共代碼的提取,剩下四個每一個是一個獨立的微服務模塊,因此咱們要部署 eurekausereducationgateway 四個模塊,也就是最後會運行四個獨立的 docker 容器。

具體的業務邏輯就不作過多說明了,本文只講部署。

2.1 配置文件 application.yml

爲了本地調試和服務器部署互不影響,咱們把原來的 application.yml 拆分爲三個文件:

  • application.yml :總配置,指定應該用下面哪一個配置
  • application-dev.yml :開發環境配置
  • application-pro.yml :生成環境配置

另外爲了方便,把 Dockerfile 也放到同級目錄下。如圖:

下面是三個配置文件的代碼:

application.yml

spring:
 profiles:
 active: pro

複製代碼

application-dev.yml

eureka:
 client:
 service-url:
 defaultZone: http://localhost:8761/eureka/
 instance:
 prefer-ip-address: true

server:
 port: 8899

spring:
 application:
 name: education
 datasource:
 driver-class-name: com.mysql.jdbc.Driver
 username: root
 password: 123456
 url: jdbc:mysql://127.0.0.1/edu?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
 jpa:
 show-sql: true
  # 若是字段值爲null則不返回
 jackson:
 default-property-inclusion: non_null

 rabbitmq:
 host: localhost
 port: 5672
 username: guest
 password: guest

 redis:
 port: 6379
 database: 0
 host: 127.0.0.1
 password:
 jedis:
 pool:
 max-active: 8
 max-wait: -1ms
 max-idle: 8
 min-idle: 0
 timeout: 5000ms

複製代碼

application-pro.yml

eureka:
 client:
 service-url:
 defaultZone: ${SPRING-CLOUD-EUREKA-ZONE}
 instance:
 prefer-ip-address: true

server:
 port: 8899

spring:
 application:
 name: education
 datasource:
 driver-class-name: com.mysql.jdbc.Driver
 username: root
 password: 123456
 url: jdbc:mysql://${SPRING-CLOUD-MYSQL-HOST}/${SPRING-CLOUD-DB-NAME}?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
 jpa:
 show-sql: true
  # 若是字段值爲null則不返回
 jackson:
 default-property-inclusion: non_null

 rabbitmq:
 host: ${SPRING-CLOUD-RABBIT-MQ-HOST}
 port: 5672
 username: guest
 password: guest

 redis:
 port: 6379
 database: 0
 host: ${SPRING-CLOUD-REDIS-HOST}
 password:
 jedis:
 pool:
 max-active: 8
 max-wait: -1ms
 max-idle: 8
 min-idle: 0
 timeout: 5000ms
複製代碼

這個項目配置比較全,redis、rabbitMQ、mysql、jpa 都有配置。

dev 跟 pro 的配置差很少,只是把 dev 中的 localhost127.0.0.1 這兩個本地的地址,換成了諸如 ${SPRING-CLOUD-EUREKA-ZONE}${SPRING-CLOUD-RABBIT-MQ-HOST} 等變量。

那這些變量是在哪設置的呢?待會兒編寫 Dockerfile 的時候就能夠看到,會在 Dockerfile 裏設置這幾個變量爲環境變量,當啓動 Docker 容器的時候,程序就會讀取到 Dockerfile 中設置的值並應用到項目中。

2.2 編寫Dockerfile

下面是 education 模塊的 Dockerfile

FROM java:8
VOLUME /tmp ADD education.jar app.jar RUN bash -c 'touch /app.jar' 
ENV SPRING-CLOUD-EUREKA-ZONE http://123.456.789.10:8761/eureka/
ENV SPRING-CLOUD-MYSQL-HOST 123.456.789.10
ENV SPRING-CLOUD-DB-NAME edu
ENV SPRING-CLOUD-RABBIT-MQ-HOST 123.456.789.10
ENV SPRING-CLOUD-REDIS-HOST 123.456.789.10

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] EXPOSE 8899
複製代碼

簡單的解釋下每句話的做用

FROM java:8 : 指定基礎鏡像,必須爲第一個命令

VOLUME /tmp : 用於指定持久化目錄

ADD education.jar app.jar : 將本地文件 education.jar 添加到容器中並命名爲 app.jar。注意這裏的 education.jar 要換成你本身項目打包出來的 jar 包名字,若是你打的包名字叫 abc.jar,那應該這麼寫:ADD abc.jar app.jar

RUN bash -c 'touch /app.jar' : 在鏡像容器中執行的命令,運行 jar 包。

ENV *** : 這幾行以 ENV 開頭的是設置環境變量,還記得上面 application-pro.yml 文件裏的那幾個 ${} 變量嗎?就是在這裏設置的。把該填地址的地方都換成這臺服務器的公網 ip 地址,本配置假設你服務器的地址是 123.456.789.10 ,用的時候把這個地址換成你本身服務器地址便可。

ENTRYPOINT *** : 配置容器,使其可執行化。

EXPOSE 8899 : 對外暴露 8899 端口。這個端口要和項目的配置文件中 server.port 設置的端口一致。

總結一下,Dockerfile 文件你要改的,只有三個地方:

  • 第三行 education.jar 換成你打包出來的 jar 包名字
  • ENV 開頭的環境變量本身根據 application-pro.yml 的配置進行設置
  • 最後一行 EXPOSE 8899 改爲你項目的端口號

再貼一個模塊的 Dockerfile 做對比:

FROM java:8
VOLUME /tmp ADD gateway.jar app.jar RUN bash -c 'touch /app.jar' 
ENV SPRING-CLOUD-EUREKA-ZONE http://123.456.789.10:8761/eureka/
ENV SPRING-CLOUD-REDIS-HOST 123.456.789.10

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] EXPOSE 8888
複製代碼

按照這種方法,把每一個須要打包的微服務項目的 Dockerfile 寫好。

2.3 打包

配置好三個 applicaiton.yml 和 Dockerfile(其實打包這一步用不到 Dockerfile),在項目的根目錄下執行如下命令打包:

mvn clean package -Dmaven.test.skip=true
複製代碼

看到控制檯輸出 SUCCESS 則打包成功

打完的包在 項目目錄/target 裏,如圖:

檢查一下 jar 包的大小,若是是好幾十 M 就沒啥問題,若是是幾百 K 那就是打包配置有問題,檢查 pom.xml 文件的 <build> 標籤配置是否正確。

<build> 配置:

<build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>repackage</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
    <finalName>education</finalName>
  </build>
複製代碼

2.4 編寫自動化腳本

寫完 Dockerfile 文件還要執行命令打包成 image 鏡像,還須要運行起容器,兩行代碼雖然很少但每次寫仍是麻煩,把它封裝成一個 sh 腳本,每次直接運行腳本省時省力。

新建 education_deploy.sh 文件,把兩行代碼放進去:

docker build -t education .
docker run -p 8899:8899 -t -dit --restart=always education
複製代碼

注意第一行最後有個點 . ,若是你想把打出來的鏡像名叫 abc,對外暴露的端口是 6666,則應該這樣寫:

docker build -t abc .
docker run -p 6666:6666 -t -dit --restart=always abc
複製代碼

2.4 上傳到服務器

新建一個文件夾,併爲每一個微服務模塊新建一個文件夾用於存放 jar 包、Dockerfile 和自動化部署文件,目錄結構如圖:

把 back_end 這個文件夾總體壓縮,壓縮命令爲:

tar -cvf back_end.tar ./back_end
複製代碼

執行完後會在目錄下看到 back_end.tar 壓縮文件。

使用 ssh 命令登陸到服務器,根目錄下新建一個 edu 文件夾,進入這個文件夾,查看當前目錄,記住這個目錄

//新建文件夾 edu
mkdir edu

//進入到 edu 文件夾內
cd edu

//查看當前目錄,會輸出:/root/edu
pwd
複製代碼

記住你要傳到服務器的位置:/root/edu,再回到本機剛纔壓縮 back_end.tar 文件的目錄,執行如下命令把 back_end.tar 發送到服務器的 /root/edu 目錄下:

scp back_end.tar root@123.456.789.10:/root/edu
複製代碼

上傳完以後,在服務器解壓

tar -xvf back_end.tar
複製代碼

而後依次進入到各個模塊的文件夾內,執行 sh 腳本

sh ./education_deploy.sh
複製代碼

都運行完以後後端微服務就部署完啦!

2.5 經常使用 Docker 命令

部署完還要檢驗是否部署正確,先從 Docker 開始檢查,最後在瀏覽器輸入接口地址看可否調通。

下面的命令都在 CentOS 服務器上執行。

查看當前運行的容器,看 mysql、redis、rabbitMQ 和你本身的項目是否運行

docker ps
複製代碼

查看日誌

想進入到容器中查看日誌:

docker logs 容器id
複製代碼

好比想查看容器id爲 378af204f7bc 的容器日誌,應該執行:

docker logs 378af204f7bc
複製代碼

若是容器運行了很長時間,將會產生很是多的日誌,直接使用 docker logs 會把全部日誌都打印出來,可不能夠只打印最後多少行或者從某個時間以後的日誌呢?固然能夠。

查看指定時間後的日誌,只顯示最後100行:

docker logs -f -t --since="2019-10-24" --tail=100 CONTAINER_ID
複製代碼

只打印最後50行日誌:

docker logs --tail=50 容器id
複製代碼

查看最近30分鐘的日誌:

docker logs --since 30m 容器id
複製代碼

查看某時間以後的日誌:

docker logs -t --since="2019-10-24T13:23:37" CONTAINER_ID
複製代碼

查看某時間段日誌:

docker logs -t --since="2019-10-24T13:23:37" --until "2019-10-25T12:23:37" CONTAINER_ID
複製代碼

中止和啓動

中止容器

docker stop 容器id
複製代碼

查看全部容器(包括已經中止的)

docker ps -a
複製代碼

從新啓動容器(容器被中止了,但還未被刪除)

docker start 容器id
複製代碼

刪除容器和鏡像

若是項目有改動,最好把以前的容器、鏡像都刪掉,再運行新的容器。

先中止容器

docker stop 容器id
複製代碼

再刪除容器

docker rm 容器id
複製代碼

查看 image 鏡像

docker images
複製代碼

刪除鏡像

docker rmi 鏡像id
複製代碼

3、前端部署

先把前端項目打包,壓縮爲 tar 文件,發送到服務器上,在服務器解壓。

要用 nginx 作代理須要先安裝 nginx

3.1 安裝 nginx

先下載安裝基礎庫

yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
yum -y install wget httpd-tools vim
複製代碼

安裝 nginx

sudo yum install nginx
複製代碼

3.2 配置 nginx

nginx 的配置文件目錄

nginx主配置文件
/etc/nginx/nginx.conf
/etc/nginx
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf
複製代碼

咱們來看 nginx.conf 默認的配置是什麼樣

# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }

}
複製代碼

修改 nginx.conf 的 server 節點,咱們依然監聽 80端口,改 server_name 爲你的域名,而後修改 locationroot 爲前端文件所在目錄,index 爲入口文件。

location / {
    root	/root/edu/front_end/;
    index	index.html index.htm;
}
複製代碼

只改這兩處便可,別的地方不要動。

server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  www.abc.cn abc.cn;
    root         /usr/share/nginx/html;

  # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
        root	/root/edu/front_end/;
        index	index.html index.htm;
    }

        error_page 404 /404.html;
        location = /40x.html {
    }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}
複製代碼

改完保存成功以後,檢查 nginx 配置,結果出現 successful 表示配置文件沒有語法錯誤

nginx -t -c /etc/nginx/nginx.conf
複製代碼

從新加載配置

nginx -s reload -c /etc/nginx/nginx.conf
複製代碼

3.3 nginx 報錯整理

[error] open() "/var/run/nginx.pid" failed

從新加載配置時有時會報錯:nginx: [error] open() "/var/run/nginx.pid" failed (2: No such file or directory)

解決方法:依次執行下面兩行代碼

sudo nginx -c /etc/nginx/nginx.conf
nginx -s reload
複製代碼

瀏覽器訪問報 403

用瀏覽器訪問域名,報 403 錯誤,要具體看究竟是哪裏出錯了能夠查看 nginx 錯誤日誌,錯誤日誌在哪放着呢? nginx.conf 文件裏指明瞭:error_log /var/log/nginx/error.log;

用 cat 命令查看文件內容

cat /var/log/nginx/error.log
複製代碼

若是報了 Permission denied,有很大多是當前登陸用戶跟 nginx.conf 文件第一行聲明的用戶不匹配。

connect() to 127.0.0.1:8000 failed (13: Permission denied)....
複製代碼

user nginx; 改成 user root; 再次從新加載配置通常就能夠解決。


以上就是部署先後端的所有內容,大佬們有問題能夠在評論區交流。

相關文章
相關標籤/搜索