5w 字 | 172 圖 | 超級賽亞級 Spring Cloud 實戰
阿新 • • 發佈:2020-11-26
# 一、PassJava 專案簡介
- PassJava-Learning 專案是 PassJava(佳必過)專案的學習教程。對架構、業務、技術要點進行講解。
- PassJava 是一款 Java `面試刷題` 的開源系統,可以用零碎時間利用小程式檢視常見面試題,夯實 Java 基礎。
- PassJava 專案可以教會你如何搭建 SpringBoot 專案,Spring Cloud 專案
- 採用流行的技術,如 SpringBoot、MyBatis、Redis、 MySql、 MongoDB、 RabbitMQ、Elasticsearch,採用 Docker 容器化部署。
## 專案地址
* [後臺平臺] https://github.com/Jackson0714/PassJava-Platform
* [後臺管理] https://github.com/Jackson0714/PassJava-Portal
* [學習教程] https://github.com/Jackson0714/PassJava-Learning
## 專案演示
- 後臺管理系統
![新增題目管理選單](https://img-blog.csdnimg.cn/img_convert/866510c591251240b829d2f7980ef07b.png)
- 小程式
![mark](https://img-blog.csdnimg.cn/img_convert/7a4d7b011a0bbe21f13195b9283644a9.png)
![mark](https://img-blog.csdnimg.cn/img_convert/a32ccc056c4cb4dd0abc99219add63cb.gif)
## PassJava 中使用的技術
SpringBoot、MyBatis、Redis、 MySql、 MongoDB、 RabbitMQ、Elasticsearch
## PassJava 實現的功能概覽
![mark](https://img-blog.csdnimg.cn/img_convert/a32ccc056c4cb4dd0abc99219add63cb.gif)
## PassJava 資料庫表概覽
![mark](https://img-blog.csdnimg.cn/img_convert/a7a551d9a02e2a076d4ddedf1d6044e9.png)
### 資料庫表字首說明
- ums_*:會員模組相關表
- cms_*:內容管理模組相關表
- qms_*:題目模組相關表
- chms_*:渠道模組相關表
- sms_*:學習模組相關表
# 二、專案微服務架構圖
## 微服務架構圖
![mark](https://img-blog.csdnimg.cn/img_convert/fd15d39ef23745a08f1bc0ff811de891.png)
![mark](https://img-blog.csdnimg.cn/img_convert/742b30efc63815b463261e3b1d40b412.png)
# 三、專案前置要求
> 由於 PassJava 專案涉及到很多知識點,希望大家先補下功課,推薦的書籍如下。
## 推薦資料
### IDEA
《IntelliJ-IDEA-Tutorial》:[https://github.com/judasn/IntelliJ-IDEA-Tutorial](https://github.com/judasn/IntelliJ-IDEA-Tutorial)
### Spring
《Spring 實戰(第 4 版)》:[https://book.douban.com/subject/26767354/](https://book.douban.com/subject/26767354/)
### SpringBoot
《Spring Boot 實戰》:[https://book.douban.com/subject/26857423/](https://book.douban.com/subject/26857423/)
### MyBatis
《MyBatis 從入門到精通》:[https://book.douban.com/subject/27074809/](https://book.douban.com/subject/27074809/)
### MySql
《深入淺出 MySQL》:[https://book.douban.com/subject/25817684/](https://book.douban.com/subject/25817684/)
### Linux
《循序漸進 Linux(第 2 版)》:[https://book.douban.com/subject/26758194/](https://book.douban.com/subject/26758194/)
### Elasticsearch
《Elasticsearch 權威指南》:[https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html](https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html)
《Elasticsearch 技術解析與實戰》:[https://book.douban.com/subject/26967826/](https://book.douban.com/subject/26967826/)
### Mongodb
《MongoDB 實戰 (第二版)》:[https://book.douban.com/subject/27061123/](https://book.douban.com/subject/27061123/)
### Docker
《Spring Cloud 與 Docker 微服務架構實戰》:[https://book.douban.com/subject/27028228/](https://book.douban.com/subject/27028228/)
# 四、環境搭建篇
## 4.1 Vagrant 快速搭建 Ubuntu 虛擬機器環境
### 1. 開啟虛擬機器服務
Windows 啟動配置:Intel Virtualization Technology -> Enabled
### 2. 下載安裝 VirtualBox
VirtualBox:虛擬機器管理軟體
https://www.virtualbox.org/wiki/Downloads
### 3. 下載安裝 Vagrant
Vagrant:建立和管理虛擬機器
Vagrant 軟體:https://www.vagrantup.com/downloads.html
Vagrant 官方映象:https://app.vagrantup.com/boxes/search
![mark](https://img-blog.csdnimg.cn/img_convert/e9960e30ba28315b116e251b313b6295.png)
- check 是否安裝好了 vagrant
命令列輸入 vagrant
```shell
vagrant
```
![mark](https://img-blog.csdnimg.cn/img_convert/31500d847899a2c72ca05a299a7a71bb.png)
### 4. 安裝 vagrant ubuntu 國內映象
```
# ubuntu 18.04 LTS:
vagrant box add https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cloud-images/bionic/current/bionic-server-cloudimg-amd64-vagrant.box --name ubuntu18
# ubunt 16.04 LTS:
vagrant box add https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cloud-images/xenial/current/xenial-server-cloudimg-amd64-vagrant.box --name ubuntu16
# ubuntu14:
vagrant box add https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cloud-images/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box --name ubuntu14
```
安裝 ubuntu 18
```shell
vagrant box add https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cloud-images/bionic/current/bionic-server-cloudimg-amd64-vagrant.box --name ubuntu18
```
![mark](https://img-blog.csdnimg.cn/img_convert/a9724236ed3a1ee5d2a4698816a5a93d.png)
- 建立 vagrant 配置檔案
```
vagrant init
```
- 開啟 C:\Users\Administrator\Vagrantfile 檔案
```powershell
config.vm.box = "base" 修改為
config.vm.box = "ubuntu18"
```
### 5. 啟動虛擬機器
```shell
vagrant up
```
![mark](https://img-blog.csdnimg.cn/img_convert/b5f802b55ce46f50fc33ed0cac6032e7.png)
![mark](https://img-blog.csdnimg.cn/img_convert/cd91791fbfab21d11f1c219596f5a55a.png)
### 6. 連線虛擬機器
```
vagrant ssh
```
![mark](https://img-blog.csdnimg.cn/img_convert/0d56fdfc6f44a4b2c9d39eb65247229b.png)
### 7. 配置密碼登入
- 配置密碼登入 vagrant
```sh
Vagrant ssh 進入系統之後
sudo su
編輯 sshd_config
vi /etc/ssh/sshd_config
PasswordAuthentication no 改為 PasswordAuthentication yes
PermitRootLogin prohibit-password 改為 PermitRootLogin yes
重啟服務
service sshd restart
```
- 安裝 XShell 工具和 XFTP 工具
- XShell 連線虛擬機器
賬號:root
密碼:vagrant
- ![mark](https://img-blog.csdnimg.cn/img_convert/25c991f93f36523e41b85c843e437103.png)
![連線成功](https://img-blog.csdnimg.cn/img_convert/b60de12b7ae98cdae73e9ec6bce67e9b.png)
## 4.2 配置虛擬機器網路
### 1.檢視VirtualBox Host-Only Network
![mark](https://img-blog.csdnimg.cn/img_convert/42d31be364ee2eee8e92ab404de8f098.png)
本地VirtualBox 網路地址 `192.168.56.1`,則修改虛擬機器IP地址為同一個網段下,比如`192.168.56.10`
### 2.配置虛擬機器IP地址
開啟Vagrant 配置檔案 C:\Users\Administrator\Vagrantfile
```powershell
# config.vm.network "private_network", ip: "192.168.33.10"
修改為
config.vm.network "private_network", ip: "192.168.56.10"
```
### 3.重新載入虛擬機器
```shell
vagrant reload
```
### 4.檢視虛擬機器IP地址
虛擬機器IP地址:192.168.56.10,和配置檔案中的一致
![mark](https://img-blog.csdnimg.cn/img_convert/3450233500ccdf9d238d2ddc65c0ead6.png)
### 5.測試本機是否可以ping通虛擬機器
ping 192.168.56.10,可以ping通
![mark](https://img-blog.csdnimg.cn/img_convert/1bc34cf9ec234346d572f8edded2211f.png)
### 6.測試虛擬機器是否可以ping通本機
ping 192.168.10.160,可以ping通
## 4.3 安裝docker
https://docs.docker.com/engine/install/ubuntu/
### 1.解除安裝老版本docker
```sh
sudo apt-get remove docker docker-engine docker.io containerd runc
```
### 2.設定倉庫
```sh
// 命令1
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
```
```sh
// 命令2
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
// 命令3
sudo apt-key fingerprint 0EBFCD88
// 命令4
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
```
### 3.安裝docker
```sh
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
```
### 4.測試安裝成功
```sh
sudo docker run hello-world
```
![mark](https://img-blog.csdnimg.cn/img_convert/ea47d2b76157bfa3e9532bde3445523b.png)
### 5.設定開機自啟動
sudo systemctl enable docker
### 6.配置映象加速
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
![mark](https://img-blog.csdnimg.cn/img_convert/2563c4c6c599340243fb5dbd54835256.png)
```sh
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["您的專屬加速器地址"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
```
### 7. 免sudo使用docker命令
當以普通使用者身份去使用docker images時,出現以下錯誤:
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.26/images/json: dial unix /var/run/docker.sock: connect: permission denied
可以看都,最後告知我們時許可權的問題。那麼在linux檔案許可權有三個資料左右drwxrwxrwx,
![img](https://img-blog.csdnimg.cn/img_convert/8d5547d30a51fe09366b5f9464c88372.png)
其中第一為d代表該檔案是一個資料夾
前三位、中三位、後三位分別代表這屬主許可權、屬組許可權、其他人許可權。
如圖,其中 第三列、第四列分別代表檔案的屬主、屬組。
上圖是報錯檔案的許可權展示,可以看到其屬主為root,許可權為rw,可讀可寫;其屬組為docker,許可權為rw,可讀可寫。如果要當前使用者可直接讀取該檔案,那麼我們就為當前使用者新增到docker屬組即可。
如果還沒有 docker group 就新增一個:
```
sudo groupadd docker
將使用者加入該 group 內。然後退出並重新登入就生效啦。
sudo gpasswd -a ${USER} docker
重啟 docker 服務
sudo service docker restart
切換當前會話到新 group 或者重啟 X 會話
newgrp - docker
注意:最後一步是必須的,否則因為 groups 命令獲取到的是快取的組資訊,剛新增的組資訊未能生效,所以 docker images 執行時同樣有錯。
```
### 8. apt-get update更新慢
Ubantu 18.04 apt-get update 無法更新,更新慢的問題 https://blog.csdn.net/stopping5/article/details/80493643
```sh
sudo cp /etc/apt/sources.list /etc/apt/sources.list.old
sudo vim /etc/apt/sources.list
替換成阿里源
#阿里源:
deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse
```
其他命令
docker update redis --restart=always 虛擬機器重啟後,redis自動啟動
docker update mysql --restart=always 虛擬機器重啟後,mysql自動啟動
## 4.4 docker 安裝mysql
### 1.下載映象
```sh
sudo docker pull mysql:5.7
```
```
ubuntu@VM-0-13-ubuntu:~$ sudo docker pull mysql:5.7
5.7: Pulling from library/mysql
c499e6d256d6: Pull complete
22c4cdf4ea75: Pull complete
6ff5091a5a30: Pull complete
2fd3d1af9403: Pull complete
0d9d26127d1d: Pull complete
54a67d4e7579: Pull complete
fe989230d866: Pull complete
466a91a95e2f: Pull complete
3e4554c238f1: Pull complete
603b48ead88c: Pull complete
1e86a9aa7171: Pull complete
Digest: sha256:fbaeced79cfdae5d3c8d4a8c41e883f254f72ed7428c6b93a498824b76d97121
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
```
### 2.檢視下載的映象
```sh
sudo docker images
```
![mark](https://img-blog.csdnimg.cn/img_convert/84dfccb1eb1e69ee0a1c35b46b8f88b2.png)
### 3.建立mysql例項並啟動
- 建立mysql例項並啟動
```sh
sudo docker run -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
引數說明
-p 3306:3306 將容器的3306埠對映到主機
-v /mydata/mysql/log:/var/log/mysql\ 將日誌檔案掛載到主機
-v /mydata/mysql/data:/var/lib/mysql\ 將資料檔案掛載到主機
-v /mydata/mysql/conf:/etc/mysql\ 將配置檔案掛載到主機
```
![mark](https://img-blog.csdnimg.cn/img_convert/0c01a36c0e874ceb4df96be8c144dc9e.png)
- 檢視docker容器
mysql容器已啟動
![mark](https://img-blog.csdnimg.cn/img_convert/d17fc5332c67ba14e86aecf7918d3746.png)
### 4.連線資料庫
- 用Workbench連線資料庫
![mark](https://img-blog.csdnimg.cn/img_convert/6f042d3678b7233135e13ffd3e029d47.png)
- 檢視資料庫
![mark](https://img-blog.csdnimg.cn/img_convert/c2721975b1ac41de2025070234f95dbf.png)
### 5.進入mysql 容器
```sh
sudo docker exec -it mysql /bin/bash
```
![mark](https://img-blog.csdnimg.cn/img_convert/8ce024ee2505f9d239c00a3a026ab157.png)
### 6.檢視虛擬機器對映檔案
```sh
cd /mydata/mysql
ls
```
![mark](https://img-blog.csdnimg.cn/img_convert/bc8e12f00c85366543d384d4874d65c8.png)
### 7.修改mysql賬號密碼
```sh
1.進入mysql容器
docker exec -it mysql /bin/bash
2.登入mysql
mysql -u root -p
輸入密碼:root
3.切換資料庫
use mysql
4.查詢root使用者
select * from user where user = root;
5.修改密碼
update user set authentication_string = password('新的密碼'), password_expired = 'N', password_last_changed = now() where user = 'root';
6.這條命令暫不清楚
update user set plugin="mysql_native_password";
7.重新整理許可權
flush privileges;
8.退出
quit;
9.重新登入
mysql -u root -p
輸入新的密碼,登入成功
```
### 8.其他命令
- 設定容器在機器重啟後自動啟動
```sh
docker update 84c --restart=always
```
## 4.5 docker安裝redis
### 1.下載映象
- 下載映象
```sh
sudo docker pull redis
```
```sh
ubuntu@VM-0-13-ubuntu:~$ sudo docker pull redis
Using default tag: latest
latest: Pulling from library/redis
c499e6d256d6: Already exists
bf1bc8a5a7e4: Pull complete
7564fb795604: Pull complete
ec6e86f783e4: Pull complete
1371d6223f46: Pull complete
021fd554320f: Pull complete
Digest: sha256:a732b1359e338a539c25346a50bf0a501120c41dc248d868e546b33e32bf4fe4
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
```
- 檢視下載的映象
```sh
sudo docker images
```
![mark](https://img-blog.csdnimg.cn/img_convert/13e3fc28537d6d792082fb6faefd8122.png)
### 2.啟動redis
- 建立redis.conf 配置檔案
```sh
sudo mkdir -p /mydata/redis/conf
sudo touch /mydata/redis/conf/redis.conf
```
- 啟動redis
```sh
sudo docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data \
-v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf
```
![mark](https://img-blog.csdnimg.cn/img_convert/e4842982f6ae3779b8032d4d80e0d5a7.png)
### 3.連線redis
```sh
sudo docker exec -it redis redis-cli
```
### 4.測試redis
設定a=100,返回OK
```sh
set a 100
```
獲取a的值,返回"100"
```sh
get a
```
![mark](https://img-blog.csdnimg.cn/img_convert/0e4da16b4bb3cf92b94ddd657dcea091.png)
### 5.設定redis持久化儲存
- 修改虛擬機器對映的redis配置檔案
```sh
修改配置檔案:
sudo vim /mydata/redis/conf/redis.conf
新增配置:
appendonly yes
```
- 檢查是否生效
```sh
重啟redis容器:
docker restart redis
設定a=200,返回OK
set a 200
獲取a的值,返回"200"
get a
重啟redis容器
sudo docker restart redis
重新連線redis容器
sudo docker exec -it redis redis-cli
獲取a的值
get a,返回"200"
```
### 6.安裝redis視覺化工具
- 安裝redis視覺化工具
redis-desktop-manager
- 連線redis
![mark](https://img-blog.csdnimg.cn/img_convert/25677482d997af86ab1a4a09ab81b5c0.png)
- 檢視redis資料庫
![mark](https://img-blog.csdnimg.cn/img_convert/306289751f9db80372f96f6210054730.png)
## 4.6 本地開發環境配置
### 1. 本地環境安裝Java
我本地環境的java版本 1.8.0_131
```sh
java -version
```
![mark](https://img-blog.csdnimg.cn/img_convert/3d48c0738d73ad1b88202796c3a5da84.png)
java安裝和環境變數配置:https://www.cnblogs.com/jackson0714/p/6591942.html
### 2.本地環境配置Maven
(1)下載Maven,拷貝資料夾到C盤
C:\apache-maven-3.6.2
(2)新增到環境變數
![mark](https://img-blog.csdnimg.cn/img_convert/78c929f3570edfeddf35d16418db6a2a.png)
cmder裡面 執行命令 mvn -v
如果報錯命令不存在,則重新啟動cmder
![mark](https://img-blog.csdnimg.cn/img_convert/129d915043b026b2df5c65f717cda911.png)
(3)設定Maven代理
阿里雲代理 https://maven.aliyun.com/mvn/view
點選使用指南,拷貝配置指南
![mark](https://img-blog.csdnimg.cn/img_convert/5784f583390f94953683b825e1f7ff15.png)
```xml
aliyunmaven
*
阿里雲公共倉庫
https://maven.aliyun.com/repository/public
```
(4)配置jdk1.8編譯專案
```xml
jdk-1.8
true
1.8
1.8
1.8
1.8
```
### 3.IDEA Maven構建工具配置
- Maven配置
![Maven配置](https://img-blog.csdnimg.cn/img_convert/0be545ab39f5a0a78a7ea98187c9d06f.png)
- 字符集配置
![字符集配置](https://img-blog.csdnimg.cn/img_convert/45a294f05dc9649eba4eb3a4b5ade38c.png)
### 4. IDEA 安裝Lombok外掛
Lombok:簡化JavaBean的開發
![mark](https://img-blog.csdnimg.cn/img_convert/d90f2eebb2476598f4a9683627493493.png)
## 5. IDEA 安裝mybatisx 外掛
mybatisx:mybatis plus開發的一個外掛,從mapper方法快速定位到xml檔案
![mark](https://img-blog.csdnimg.cn/img_convert/19b047b7b5bd17188b1563b4b6847916.png)
### 6.安裝VSCode
https://code.visualstudio.com/
![mark](https://img-blog.csdnimg.cn/img_convert/f0e30a639bd7f2e20314bc417f0db492.png)
### 7.新增VSCode外掛
![mark](https://img-blog.csdnimg.cn/img_convert/6b2cb9fc9e3b1aa0d2b7dd6db7201fe4.png)
- Auto Close Tag 自動加上關閉標籤
![mark](https://img-blog.csdnimg.cn/img_convert/f56875ecb1f979b0c7079554d69ba687.png)
- Auto Rename Tag 自動命名配對標籤
![mark](https://img-blog.csdnimg.cn/img_convert/94494cea16ce6cec4f140072b056a581.png)
- Chinese 中文簡體包
![mark](https://img-blog.csdnimg.cn/img_convert/0011e42e435aae0121b916cd585b641d.png)
- ESLint 語法檢查
![mark](https://img-blog.csdnimg.cn/img_convert/873c0206b1f01f2ccdcdce1ddcb14012.png)
- HTML CSS Support 幫助CSS開發
![mark](https://img-blog.csdnimg.cn/img_convert/be45d520d8202cfad826aa04612a8609.png)
- HTML Snippets 幫忙HTML開發
![mark](https://img-blog.csdnimg.cn/img_convert/dba9a80e44d80a20692e3aa424928741.png)
- JavaScript (ES6) 幫助JavaScript開發
![mark](https://img-blog.csdnimg.cn/img_convert/140da0df1dc2d88c40bfa14b9e5afecb.png)
- Liver Server 啟動一個本地服務
![mark](https://img-blog.csdnimg.cn/img_convert/b2223c025b8b7d09842602ec58709995.png)
- open in browser 用瀏覽器開啟檔案
![mark](https://img-blog.csdnimg.cn/img_convert/2acab08aff9730363ccc223fe3c89ced.png)
- Vetur 幫助Vue開發
![mark](https://img-blog.csdnimg.cn/img_convert/8c18f7c5ace8d9ae8f2f3a118b8265f4.png)
- minapp 幫助小程式開發
![mark](https://img-blog.csdnimg.cn/img_convert/170bf7d8d3141845eed0849fcc5af732.png)
### 問題
1.新專案匯入main1,main2
刪除main1.iml,main2.iml
## 4.7 配置Git
### 1.配置git 使用者名稱和郵箱
```sh
git config --global user.name "jackson0714"
git config --global user.email "[email protected]"
```
### 2.生成ssh key
```sh
ssh-keygen -t rsa -b 4096 -C "[email protected]"
```
![mark](https://img-blog.csdnimg.cn/img_convert/46128a3ff299bca7490016e62d3593ef.png)
### 3.設定ssh key
- 開啟檔案
C:\Users\Administrator\.ssh\id_rsa.pub
- 拷貝里面的內容
- 開啟這個連結
https://github.com/settings/ssh/new
- 貼上已拷貝的內容
![mark](https://img-blog.csdnimg.cn/img_convert/d933638e1ffc702f1f167befb7682e18.png)
- 儲存ssh key
![mark](https://img-blog.csdnimg.cn/img_convert/6a7672dbf6df803396e11de89ed7ce05.png)
### 4.遇到的問題
如果遇到Fatal: HttpRequestException encountered問題
![mark](https://img-blog.csdnimg.cn/img_convert/76d55b5dd887f4a5bebcc009dd9602f0.png)
則下載這個安裝包解決:
[Git Credential Manager for Windows v1.20](https://github.com/microsoft/Git-Credential-Manager-for-Windows/releases/tag/1.20.0)
連結:https://github.com/Microsoft/Git-Credential-Manager-for-Windows/releases/
git每次提交都需要輸入使用者名稱和密碼
解決辦法:git config --global credential.helper store
下次提交輸入使用者名稱和密碼後就會記住了
### 5.讓一個專案同時提交到碼雲和GitHub兩個倉庫
在專案目錄裡找到.git資料夾然後找到config檔案。
開啟這個檔案後找到下面的程式碼
```
[remote "origin"]
url = git提交地址
fetch = +refs/heads/*:refs/remotes/origin/*
```
將其改成
```
[remote "origin"]
url = 碼雲Git提交地址
url = GitHub提交地址
fetch = +refs/heads/*:refs/remotes/origin/*
```
問題:
c731c6f..69bae9b master -> master
To https://gitee.com/jayh2018/passjava-portal.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'https://gitee.com/jayh2018/passjava-portal.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
## 4.8 Windows安裝mysql
### 1.安裝截圖
![mark](https://img-blog.csdnimg.cn/img_convert/a00b2ae996f016213ca1739f1d21daaf.png)
### 2.遇到的問題 1
windows用syslog連線本地mysql資料庫,提示 plugin caching_sha2_password
![mark](https://img-blog.csdnimg.cn/img_convert/da911ab016b67d28b5d84fc81e00784d.png)
解決方案:
```sql
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123';
```
![mark](https://img-blog.csdnimg.cn/img_convert/ba7911395b1fd4760b467e7c5e72322a.png)
### 2.遇到的問題 2
Host is not allowed to connect to this MySQL server
使用遠端連線mysql的時候碰到這樣的錯誤:
Host is not allowed to connect to this MySQL server。
簡單的解決方式如下:
(1)修改表。可能是你的帳號不允許從遠端登陸,只能在localhost。這個時候只要在localhost的那臺電腦,登入mysql後,更改 "mysql" 資料庫裡的 "user" 表裡的 "host" 項,從"localhost"改稱"%"
mysql -u root -p
按照提示輸入密碼
mysql>use mysql;
mysql>update user set host = '%' where user = 'root';
(2)修改完後執行如下SQL命令
flush privileges
# 五、PassJava 基礎實踐篇
## 5.1 初始化專案和新增微服務
### 1.GitHub上建立一個空的倉庫
![mark](https://img-blog.csdnimg.cn/img_convert/930e60aa6f58e57fd83f1f58cb150679.png)
### 2.從GitHub上引入空的專案
![mark](https://img-blog.csdnimg.cn/img_convert/8521a080a8861db35abcb0837b060f1e.png)
![mark](https://img-blog.csdnimg.cn/img_convert/d422209fc216efe6af2a387ece24b67f.png)
### 3.新增內容服務
passjava-content
![mark](https://img-blog.csdnimg.cn/img_convert/e303297e7119bff64378a16ff2fe7dfd.png)
![mark](https://img-blog.csdnimg.cn/img_convert/d19fb441d84c418cf00dee41d15d7b73.png)
| 序號 | 欄位 | 內容 |
| ---- | ----------- | -------------------------------- |
| 1 | group | com.jackson0714.passjava |
| 2 | Artifact | passjava-content |
| 3 | Name | passjava-content |
| 4 | Description | 佳必過-內容服務 |
| 5 | Package | com.jackson0714.passjava.content |
- 新增依賴元件SpringWeb, OpenFeign
![mark](https://img-blog.csdnimg.cn/img_convert/fdefd5ec306bf1500b729cd2a021198d.png)
![mark](https://img-blog.csdnimg.cn/img_convert/dc6134dcb84adbd0c68f374dc6376c20.png)
### 3.新增其他微服務
| 序號 | 服務描述 | 服務名 |
| ---- | ---------- | ----------------- |
| 1 | 內容微服務 | passjava-content |
| 2 | 會員微服務 | passjava-member |
| 3 | 題目微服務 | passjava-question |
| 4 | 學習微服務 | passjava-study |
| 5 | 渠道微服務 | passjava-channel |
![mark](https://img-blog.csdnimg.cn/img_convert/3ce549c69b72c84e37e2534a141a770d.png)
### 4.PassJava-Platform新增Pom.xml檔案
![mark](https://img-blog.csdnimg.cn/img_convert/5e0b9039896c962a21be34bcc49461f8.png)
```xml
4.0.0
com.jackson0714.passjava
passjava
0.0.1-SNAPSHOT
passjava
佳必過-聚合服務
pom
passjava-content
passjava-member
passjava-question
passjava-study
passjava-channel
```
### 5.新增根目錄Maven 配置
![mark](https://img-blog.csdnimg.cn/img_convert/5f8d0d930ef9d8fc4755ee8477106642.png)
![mark](https://img-blog.csdnimg.cn/img_convert/c9c1b92cd818b08a54056ac93ee40516.png)
Maven操作根專案就可以了,試下clean
![mark](https://img-blog.csdnimg.cn/img_convert/6c2f9c463b5d13022240ac462384108f.png)
![mark](https://img-blog.csdnimg.cn/img_convert/6be084f700cfa4ebc837084fd0b2f693.png)
### 6. 配置.gitignore檔案
提交程式碼時,忽略某些檔案
```json
### gradle ###
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
### STS ###
.settings/
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
bin/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
rebel.xml
### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/
### maven ###
target/
*.war
*.ear
*.zip
*.tar
*.tar.gz
**/mvnw
**/mvnw.cmd
**/.mvn
### logs ####
/logs/
*.log
### temp ignore ###
*.cache
*.diff
*.patch
*.tmp
*.java~
*.properties~
*.xml~
### system ignore ###
.DS_Store
Thumbs.db
Servers
.metadata
upload
gen_code
### database ###
db/db_back_dir/
### redis ###
/redis/
```
刪除子專案的.gitignore檔案
![mark](https://img-blog.csdnimg.cn/img_convert/0ed14558f0e8cd5f05e8460a5de6c5d4.png)
### 7.提交程式碼
可以用IDEA的git工具提交,也可以用git bash命令列提交
```sh
git add .
git commit -m 'xxx'
git push origin master
```
## 5.2 初始化資料庫和表
### 用PowerDisigner工具建立資料庫
- 用PowerDisigner工具建立資料庫
![用PowerDisigner工具建立資料庫](https://img-blog.csdnimg.cn/img_convert/5bed501192020f5323d82f6627c8f584.png)
總共有5個微服務資料庫:內容、學習、渠道、使用者、題目
![5個數據庫](https://img-blog.csdnimg.cn/img_convert/0146b313986a0c2a456ea6337f9f51a4.png)
- 內容微服務的資料庫
![內容微服務的資料庫](https://img-blog.csdnimg.cn/img_convert/693cc4886380a38b62314e233ea88930.png)
- 學習微服務的資料庫
![學習微服務的資料庫](https://img-blog.csdnimg.cn/img_convert/2048fbd5b7369d5e6954e2be1b6a28f6.png)
- 渠道微服務的資料庫
![渠道微服務的資料庫](https://img-blog.csdnimg.cn/img_convert/c25161636596b2ab25550671dfd08603.png)
- 使用者微服務的資料庫
![使用者微服務的資料庫](https://img-blog.csdnimg.cn/img_convert/ff1a63761c835b9c03982138f63f8083.png)
- 題目微服務的資料庫
![題目微服務的資料庫](https://img-blog.csdnimg.cn/img_convert/4fd3d47d61d27bb734d4424c6309a4d3.png)
SQL檔案在這個專案裡面:https://github.com/Jackson0714/PassJava-Platform.git
![SQL檔案](https://img-blog.csdnimg.cn/img_convert/dd0d4cb255a3a98787ee40040b58d63d.png)
![mark](https://img-blog.csdnimg.cn/img_convert/a7a551d9a02e2a076d4ddedf1d6044e9.png)
## 5.3 搭建管理後臺
> 管理後臺使用人人開源的後臺管理框架,完成快速搭建。
### 1.下載人人開源後臺管理框架
- renren-fast
https://gitee.com/renrenio/renren-fast.git
- renren-fast-vue
https://gitee.com/renrenio/renren-fast-vue.git
### 2.新增人人開源後端程式碼
PassJava專案
拷貝資料夾renren-fast到PassJava根目錄
POM檔案 新增依賴
```xml
renren-fast
```
### 3.初始化後臺管理資料庫
- 建立資料庫:passjava_admin
- 執行renren-fast/db/mysql.sql指令碼
![](https://img-blog.csdnimg.cn/img_convert/bdb7b8afbdfb8241aa4d3bd1ac437ad3.png)
### 4.修改renren-fast 服務的配置檔案
檔案路徑:src/main/resources/application-dev.yml
- 修改資料庫連線為自己的mysql資料庫連線
![mark](https://img-blog.csdnimg.cn/img_convert/8fb469d11b5815be7ed1189304314ed9.png)
### 5.啟動renren-fast服務
- 配置SDK為1.8
![mark](https://img-blog.csdnimg.cn/img_convert/aa431cec41ff57a4e2e8647e248441fc.png)
![mark](https://img-blog.csdnimg.cn/img_convert/d0ec1621d6382a9d259fa9121c3902b3.png)-
- 執行renren-fast後臺
![mark](https://img-blog.csdnimg.cn/img_convert/578ae31161a7c27dfe93a338613856f1.png)
出現錯誤:com.mysql.cj.jdbc.exceptions.PacketTooBigException: Packet for query is too large...
解決方案:修改mysql容器的配置檔案
```sh
cd /mydata/mysql/conf
sudo vim my.cnf
新增配置,[mysqld_safe]如果有,則不需要新增
[mysqld_safe]
max_allowed_packet=32M
```
- 執行結果
![mark](https://img-blog.csdnimg.cn/img_convert/ea171e0ab96eb69d0cf5e9762f1aca17.png)
- 測試服務執行狀態
瀏覽器輸入:http://localhost:8080/renren-fast/
顯示結果:
```json
{"msg":"invalid token","code":401}
```
結果如上所示,則表示服務執行正常。另外結果裡面的invalid token說明許可權不足,不是指服務不正常。
### 6.啟動前端專案
- 配置cnpm
```sh
npm install -g cnpm --registry=https://registry.npm.taobao.org
```
- 安裝node_modules依賴包
```sh
cnpm install
```
- 打包前端專案
```sh
npm run dev
```
- 瀏覽後臺
http://localhost:8002
![mark](https://img-blog.csdnimg.cn/img_convert/df5f499f2e76ab42e5f9b82ec6844bac.png)
### 7.前後端聯調登入
- 登入後臺
賬號:admin
密碼:admin
登入成功
![mark](https://img-blog.csdnimg.cn/img_convert/900d837ec9ebbaa97d830430d879b66d.png)
- 檢視後端服務日誌
![mark](https://img-blog.csdnimg.cn/img_convert/ce210d30ea94a017256e7f42206341a8.png)
說明前端登入請求傳送到了後端服務,並驗證了使用者名稱和密碼是否正確。
## 5.4 自動生成前後端程式碼
### 1.下載程式碼生成器框架
```sh
git clone https://gitee.com/renrenio/renren-generator.git
```
### 2.新增人人開源後端程式碼
PassJava專案
拷貝資料夾renren-fast到PassJava根目錄
POM檔案 新增依賴
```xml
renren-generator
```
### 3.修改renren-generator服務的配置檔案
(1)修改資料庫連結 src/main/resources/application-dev.yml
- 修改資料庫連線為自己的mysql資料庫連線
- 資料庫名改為要生成程式碼的服務,如passjava_qms資料庫
```xml
url: jdbc:mysql://129.211.188.xxx:3306/passjava_qms?useUnicode=true&characterEncoding=UTF-8&useSSL=false
username: root
password: root
```
(2)修改屬性配置檔案 src/main/resources/generator.properties
```properties
# 以question微服務為例
mainPath=com.jackson0714
package=com.jackson0714.passjava
moduleName=question
author=jackson0714
[email protected]
tablePrefix=qms_
```
(3)修改controller 模板檔案
src/main/resources/template/Controller.java.vm
刪除引入的包,後面再引入
```java
import org.apache.shiro.authz.annotation.RequiresPermissions;
```
註釋RequiresPermissions註解,後面再引入
```java
@RequiresPermissions("${moduleName}:${pathName}:list")
```
### 4.啟動程式碼生成器服務
![啟動程式碼生成器服務](https://img-blog.csdnimg.cn/img_convert/1e4c863ccb02f4716d60e8bb043ae726.png)
瀏覽器開啟localhost,可以看到資料庫qms的兩張表已經顯示在後臺了
![mark](https://img-blog.csdnimg.cn/img_convert/c9a081a078d6c82229f8bf7382650468.png)
### 5.生成程式碼
- 生成程式碼
![生成程式碼](https://img-blog.csdnimg.cn/img_convert/b12f3c9b34f0430acca4519f5b3dc67e.png)
![程式碼生成器生成的pms服務程式碼](https://img-blog.csdnimg.cn/img_convert/cfc3922f3e11034132953a2637fc8095.png)
- 拷貝main資料夾到question模組src目錄
- 刪除前端程式碼passjava-question\src\main\resources\src目錄
- 程式碼結構
![程式碼結構](https://img-blog.csdnimg.cn/img_convert/b7fb3f85cf7320b6870c2ffd31acbd8a.png)
生成的程式碼包含controller,dao層,實體類,介面實現類,mapper對映檔案
### 6.新增common 模組
因為自動生成的程式碼引用了一些工具類,而我們的專案中沒有,所以需要加個common模組新增一些工具類
![引用工具類報錯](https://img-blog.csdnimg.cn/img_convert/0fb4e09bab1a5795bdbbe7b5cfff7c4b.png)
- 新增passjava-common
New Module: 選擇Maven
![選擇Maven](https://img-blog.csdnimg.cn/img_convert/3c3011374f8dd6d2ff7e54b468afa39a.png)
Name: passjava-common
![新增common模組](https://img-blog.csdnimg.cn/img_convert/cb1b4f25e3a0d62ca62a53a839b6e464.png)
### 7.question模組新增common模組依賴
pom檔案新增依賴
```xml
com.jackson0714.passjava
passjava-common
0.0.1-SNAPSHOT
```
### 8.common模組新增依賴
- MyBatis-Plus
```xml
com.baomidou
mybatis-plus
3.2.0
```
- lombok依賴
```xml
org.projectlombok
lombok
1.18.12
```
- httpcore依賴
```xml
org.apache.httpcomponents
httpcore
4.4.12
```
- commons-lang依賴
```xml
commons-lang
commons-lang
2.6
```
- servlet依賴
```xml
javax.servlet
servlet-api
2.5
provided
```
### 9.common模組新增工具類
- 新增包com.jackson0714.common.utils
- 從renren-fast專案copy檔案
`Constans.java`、`PageUtils.java`、`Query.java`、`R.java`、`RRException.java`
- 新增包`com.jackson0714.common.xss`
- 從renren-fast專案copy檔案
`HTMLFilter.java`、`SQLFilter.java`
![passjava-common程式碼結構圖](https://img-blog.csdnimg.cn/img_convert/6464ffbfc7aacb05eae26d0a02a13844.png)
![拷貝renren-fast檔案](https://img-blog.csdnimg.cn/img_convert/18bc241b134851652dc629239e7e1b7e.png)
## 5.5 整合MyBatis-Plus實現CRUD
### 1.新增Mybatis-Plus依賴
```xml
com.baomidou
mybatis-plus-boot-starter
3.2.0
```
### 2.配置資料來源
- 匯入資料庫的驅動
- 檢視mysql版本 5.7.29
![mark](https://img-blog.csdnimg.cn/img_convert/37a4f54f0dd5abc401c63f4da238a319.png)
到maven倉庫檢視適用的mysql驅動,5.7的沒有,8.0相容5.7的,所以選擇8.0的驅動
```xml
mysql
mysql-connector-java
8.0.17
```
### 3.配置MyBatis-Plus
- 新增application.yml 檔案配置資料來源
檔案路徑:/passjava-question/src/main/resources/application.yml
```yaml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://129.211.188.xxx:3306/passjava_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: xxx
```
- 配置mapper對映檔案路徑
![配置mabatis-plus時的智慧提示](https://img-blog.csdnimg.cn/img_convert/aac86b95a6ed85060516aa66256c14da.png)
```yxml
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
```
- 新增MapperScan註解
```java
@MapperScan("com.jackson0714.passjava.question.dao")
@SpringBootApplication
public class PassjavaQuestionApplication {
public static void main(String[] args) {
SpringApplication.run(PassjavaQuestionApplication.class, args);
}
}
```
### 4.測試mybatis-plus的CRUD方法
- 建立型別為javaBasic的type表資料
```java
@Autowired
TypeService typeService;
// 建立題目型別
@Test
void testCreateType() {
TypeEntity typeEntity = new TypeEntity();
typeEntity.setType("javaBasic");
typeService.save(typeEntity);
System.out.println("建立成功");
}
```
![建立型別為javaBasic的type表資料](https://img-blog.csdnimg.cn/img_convert/37931a7a5cfd78212439345aa62e4e48.png)
- 更新id=1的表資料
```java
// 更新type=jvm
@Test
void testUpdateType() {
TypeEntity typeEntity = new TypeEntity();
typeEntity.setId(1L);
typeEntity.setType("jvm");
typeService.updateById(typeEntity);
System.out.println("修改成功");
}
```
![更新id=1的表資料](https://img-blog.csdnimg.cn/img_convert/2fde0b70fdf7f252ff0009f53bb57907.png)
- 查詢id=1的表資料
```
// 查詢題目型別
@Test
void testSelectType() {
List typeEntityList = typeService.list(new QueryWrapper().eq("id",1L));
typeEntityList.forEach((item)-> {
System.out.println(item);
});
System.out.println("查詢成功");
}
```
![查詢id=1的表資料](https://img-blog.csdnimg.cn/img_convert/99972b514d477666200ef20c565180f0.png)
- 刪除id=1的表資料
```java
// 刪除題目型別記錄
@Test
void testRemoveType() {
typeService.removeById(1L);
System.out.println("刪除成功");
}
```
![刪除id=1的表資料](https://img-blog.csdnimg.cn/img_convert/48df02d5b12aabc8ee7ec348c917520b.png)
## 5.6 生成所有微服務的CRUD程式碼
### 1. 修改程式碼生成器配置檔案
(1)\renren-generator\src\main\resources\generator.properties
```properties
mainPath=com.jackson0714
package=com.jackson0714.passjava
moduleName=channel
author=jackson0714
[email protected]
tablePrefix=chms_
```
(2)\renren-generator\src\main\resources\application.yml
修改連線的資料庫:passjava_chms
### 2.生成渠道微服務程式碼
啟動服務,開啟瀏覽器:http://localhost:8003/#generator.html
注意:埠地址預設是8080,我配置成了8003。
![生成渠道微服務程式碼](https://img-blog.csdnimg.cn/img_convert/a11ffc7e13a61214d545f3d0cbc0dd06.png)
### 3.新增生成的程式碼
- 刪除自動生成的程式碼中的資料夾:main\resources\src
- 拷貝main資料夾到channel模組src目錄下
### 4.配置渠道微服務
- pom.xml引入common模組
```xml
com.jackson0714.passjava
passjava-common
0.0.1-SNAPSHOT
```
- 新增application.yml
```yaml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://129.211.188.xxx:3306/passjava_chms?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: xxx
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
```
- 5.測試channel服務介面
訪問:http://localhost:8000/channel/channel/list
返回:
```json
{"msg":"success","code":0,"page":{"totalCount":0,"pageSize":10,"totalPage":0,"currPage":1,"list":[]}}
```
### 5.生成所有微服務的CRUD程式碼
![生成所有微服務程式碼](https://img-blog.csdnimg.cn/img_convert/f83b53cf98278f265fb48b58d17b741c.png)
### 6.配置微服務埠
```sh
passjava-channel 埠8000
passjava-content 埠9000
passjava-member 埠10000
passjava-question 埠11000
passjava-study 埠12000
```
所有微服務都啟動成功並測試介面通過
```sh
http://localhost:8000/channel/channel/list
http://localhost:9000/content/banner/list
http://localhost:10000/member/member/list
http://localhost:11000/question/question/list
http://localhost:12000/study/studytime/list
```
![mark](https://img-blog.csdnimg.cn/img_convert/70cc0041e7c2bc980289afe4f13280cb.png)
## 5.7 管理後臺-題目型別功能
### 1.環境準備
- 程式碼準備
將renren-fast-vue程式碼copy到自己的前端專案中
- 安裝node_module
```sh
cnpm install
```
- 啟動前端portal
```sh
npm run dev
```
- 登陸後臺
1.啟動RenrenAplication
2.輸入使用者名稱和密碼登陸
![PassJava後臺](https://img-blog.csdnimg.cn/img_convert/9447e59ccd38d212247deb5caae59202.png)
### 2. 新增目錄和選單
- 新增`題目中心`目錄(一級選單)
![新增題目管理選單](https://img-blog.csdnimg.cn/img_convert/866510c591251240b829d2f7980ef07b.png)
重新整理頁面,就可以看到題目中心選單
- 新增題目`型別維護`選單(二級選單)
![題目型別維護選單](https://img-blog.csdnimg.cn/img_convert/9377f0d5ed9c460ac2a9f26c88907623.png)
![題目中心選單](https://img-blog.csdnimg.cn/img_convert/b92a461f49956c238eaccbe560656d26.png)
可以看到資料庫新增了兩條記錄,分別對應兩個選單
![sys_menu表](https://img-blog.csdnimg.cn/img_convert/40d44ec6bce09b8e54b7a9ccbbcd5fb2.png)
點選型別維護選單,打開了連結:http://localhost:8002/#/question-type,頁面顯示空白頁面.
### 3.自動生成前端頁面
用renren-generator自動生成前端程式碼,可以參考這篇:[13.SpringCloud實戰專案-自動生成前後端程式碼](http://www.passjava.cn/#/02.PassJava架構篇/04.自動生成前後端程式碼)
拷貝question目錄到前端目錄 \src\views\modules
![自動生成前端程式碼](https://img-blog.csdnimg.cn/img_convert/3c043f243f3b40d0579fa8bfec0d791e.png)
![前端Vue頁面](https://img-blog.csdnimg.cn/img_convert/7b34dcb1bd3cb7e222a5e75f854e2534.png)
### 4. 測試型別維護功能
點選型別維護選單,可以看到請求報404
http://localhost:8080/renren-fast/question/type/list?t=1587825969456&page=1&limit=10&key=
![mark](https://img-blog.csdnimg.cn/img_convert/e0aeeac276e086d5c798ffd3247c9c9d.png)
> 因為頁面的請求都訪問到renren-fast服務了,所以要修改為訪問題目微服務。但是前端有很多請求訪問的是不同的服務,所以我們可以通過閘道器來作為請求的入口,然後將不同的請求路由到不同的服務。
SpringCloud整合閘道器可以看之前寫的一篇文章:[20.SpringCloud整合Gateway閘道器](http://www.passjava.cn/#/02.PassJava架構篇/11.SpringCloud整合Gateway閘道器)
### 5.配置請求到閘道器
檔案:\static\config\index.js
api介面請求地址替換為gateway的地址
```javascript
window.SITE_CONFIG['baseUrl'] = 'http://localhost:8080/renren-fast';
替換為
window.SITE_CONFIG['baseUrl'] = 'http://localhost:8060'; // 閘道器地址
```
重新整理頁面,發現會回到登入頁面,而且驗證碼獲取不到,F12除錯工具可以看到驗證碼請求傳送到閘道器上,而閘道器上找不到這個請求地址(http://localhost:8060/captcha.jpg),所以報404。其實驗證碼請求應該訪問renren-fast服務,所以我們要將驗證碼請求通過閘道器轉發到renren-fast服務(http://localhost:8080/renren-fast/captcha.jpg)。
```json
# 驗證碼請求:
GET http://localhost:8060/captcha.jpg?uuid=1ce21f53-1866-40b1-8b20-2f4515d59f0d 404 (Not Found)
```
![獲取驗證碼報404](https://img-blog.csdnimg.cn/img_convert/f89c5068f75f1e02e7b77dedb1d38edc.png)
> 可以將renren-fast註冊到註冊中心,然後通過閘道器將請求轉發到renren-fast服務。
### 6.註冊renren-fast服務
- renren-fast專案新增common依賴
```xml
com.jackson0714.passjava
passjava-common
0.0.1-SNAPSHOT
```
- 配置註冊中心地址
```yaml
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
```
- 配置應用程式的名稱
```yaml
application:
name: renren-fast
```
- 應用類新增`@EnableDiscoveryClient`註解
- 檢視服務是否註冊成功
![Nacos服務列表](https://img-blog.csdnimg.cn/img_convert/4b7b84df67a747ec19ec01ff2eea0335.png)
### 7. 新增閘道器路由規則
- 配置路由規則
passjava-gateway專案中application.yml檔案配置路由規則,並重啟passjava-gateway服務
```yaml
spring:
cloud:
gateway:
routes:
- id: route_portal # 路由規則id
uri: lb://renren-fast # 負載均衡,renren-fast服務
predicates: # 斷言
- Path=/api/** # 如果前端請求路徑包含 api,則應用這條路由規則
filters: #過濾器
- RewritePath=/api/(?.*),/renren-fast/$\{segment} # 將訪問路徑中包含的api替換成renren-fast,但是替換的url不會在前端顯示,還是閘道器的訪問路徑。這裡不是跳轉到新的路徑,而是轉發請求。
```
- 修改前端請求路徑
檔案:\static\config\index.js
請求路徑新增`api`
```javascript
window.SITE_CONFIG['baseUrl'] = 'http://localhost:8086';
替換為
window.SITE_CONFIG['baseUrl'] = 'http://localhost:8060/api'; // 新增api
```
- 重新整理登入頁面,可以正常獲取驗證碼,請求路徑為閘道器地址 + /api/captcha
```javascript
http://localhost:8060/api/captcha.jpg?uuid=84d36089-07ae-4201-85c0-8217b032f21b
```
> 前端將請求傳送到閘道器http://localhost:8060/api/captcha.jpg,閘道器將請求轉發到http://localhost:8060/api/renren-fast/captcha.jpg。
- 登入,報跨域問題
```javascript
Access to XMLHttpRequest at 'http://localhost:8060/api/sys/login' from origin 'http://localhost:8002' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```
> 登入頁面url:http://localhost:8002,點選登入訪問的請求url:http://localhost:8060/api/sys/login,兩個url的埠號不一樣,產生了跨域問題。
### 8.跨域問題
- 跨域資源共享([CORS](https://developer.mozilla.org/zh-CN/docs/Glossary/CORS)) 是一種機制,它使用額外的 [HTTP](https://developer.mozilla.org/zh-CN/docs/Glossary/HTTP) 頭來告訴瀏覽器 讓執行在一個 origin (domain) 上的Web應用被准許訪問來自不同源伺服器上的指定的資源。當一個資源從與該資源本身所在的伺服器**不同的域、協議或埠**請求一個資源時,資源會發起一個**跨域 HTTP 請求**。
- 比如,站點 http://domain-a.com 的某 HTML 頁面通過 [ 的 src ](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Img#Attributes)請求 http://domain-b.com/image.jpg。網路上的許多頁面都會載入來自不同域的CSS樣式表,影象和指令碼等資源。
- 出於安全原因,瀏覽器限制從指令碼內發起的跨源HTTP請求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 這意味著使用這些API的Web應用程式只能從載入應用程式的同一個域請求HTTP資源,除非響應報文包含了正確CORS響應頭。
![跨域場景](https://img-blog.csdnimg.cn/img_convert/ce6e31eb0447d6cecbe103d63bb17a47.png)
[^官方文件]: https://developer.mozilla.org/zh-CN/docs/Web/http/access_control_cors
### 9.解決跨域問題
- 新增響應頭,配置當次請求允許跨域
- **Access-Control-Allow-Origin**:支援哪些來源的請求跨域
- **Access-Control-Allow-Methods**:支援哪些方法跨域
- **Access-Control-Allow-Credentials**:跨域請求預設不包含cookie,設定為true可以包含cookie
- **Access-Control-Expose-Headers**:跨域請求暴露的欄位CORS請求時,XMLHttpRequest物件的getResponseHeader()方法只能拿到6個基本欄位:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他欄位,就必須在Access-Control-Expose-Headers裡面指定。
- **Access-Control-Max-Age**:表明該響應的有效時間為多少秒。在有效時間內,瀏覽器無
須為同一請求再次發起預檢請求。請注意,瀏覽器自身維護了一個最大有效時間,如果
該首部欄位的值超過了最大有效時間,將不會生效。
- 新增跨域配置
passjava-gateway應用中新增配置類PassJavaCorsConfiguration.java
```java
package com.jackson0714.passjava.gateway.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
@Configuration
public class PassJavaCorsConfiguration {
@Bean
public CorsWebFilter corsWebFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 配置跨域
corsConfiguration.addAllowedHeader("*"); // 允許所有請求頭跨域
corsConfiguration.addAllowedMethod("*"); // 允許所有請求方法跨域
corsConfiguration.addAllowedOrigin("*"); // 允許所有請求來源跨域
corsConfiguration.setAllowCredentials(true); //允許攜帶cookie跨域,否則跨域請求會丟失cookie資訊
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsWebFilter(source);
}
}
```
- 註釋renren-fast裡面的跨域配置
檔案路徑:src/main/java/io/renren/config/CorsConfig.java
- 登入成功
可以看到login請求的響應報文中包含了已配置的CORS響應頭
![login請求](https://img-blog.csdnimg.cn/img_convert/f7cadfed3d382bcbcf9420896c0b0078.png)
### 10.配置題目服務的路由規則
我們訪問題目中心的型別頁面,發現還是報404找不到資源
所以我們需要配置題目服務的路由規則,將題目中心的頁面請求經閘道器轉發到題目服務。
```yaml
spring:
cloud:
gateway:
routes:
- id: route_question # 題目微服務路由規則
uri: lb://passjava-question # 負載均衡,將請求轉發到註冊中心註冊的renren-fast服務
predicates: # 斷言
- Path=/api/question/** # 如果前端請求路徑包含 api/question,則應用這條路由規則
filters: #過濾器
- RewritePath=/api/(?.*),/$\{segment} # 將跳轉路徑中包含的api替換成question
```
> 注意:若predicates的Path更精確,則將路由規則放到更上面,優先命中更上面的路由規則。
### 11.測試型別維護功能
- 資料庫插入3條測試資料
- 測試查詢列表,可以看到有三條記錄查詢出來了
![型別維護頁面](https://img-blog.csdnimg.cn/img_convert/93cde9a8d28c72c11dbe1b1adcbee0c6.png)
- 測試修改一條資料,可以看到資料庫裡面記錄更新為23了
![修改型別logo](https://img-blog.csdnimg.cn/img_convert/bff36650d842d5828eef45b16a07d95a.png)
- 測試刪除一條資料,可以看到介面和資料庫都刪除了一條資料
![mark](https://img-blog.csdnimg.cn/img_convert/de502ae0d99d749609c974efea0961e3.png)
### 12.開啟新增和批量刪除功能
註釋許可權判斷,預設返回true
```js
// src\utils\index.js
/**
* 是否有許可權
* @param {*} key
*/
export function isAuth (key) {
// return JSON.parse(sessionStorage.getItem('permissions') || '[]').indexOf(key) !== -1 || false
return true
}
```
![新增和批量刪除按鈕](https://img-blog.csdnimg.cn/img_convert/b5efe6ccfa027569bf71192527358e28.png)
## 5.8 管理後臺-題目維護功能
### 1.配置邏輯刪除
- 所有表字段新增del_flag欄位
```sql
del_flag tinyint(1) DEFAULT 0 COMMENT '刪除標記(0-正常,1-刪除)',
```
- MyBatisPlus配置邏輯刪除
```yaml
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
logic-delete-field: delFlag #全域性邏輯刪除欄位值 3.3.0開始支援,詳情看下面。
logic-delete-value: 1 # 邏輯已刪除值(預設為 1)
logic-not-delete-value: 0 # 邏輯未刪除值(預設為 0)
```
- log中列印查詢SQL語句
```sql
SELECT id,type,comments,logo_url,del_flag,create_time,update_time FROM qms_type WHERE del_flag=0
```
- log列印刪除SQL語句
```sql
UPDATE qms_type SET del_flag=1 WHERE id IN ( 1 ) AND del_flag=0
```
### 2.快速顯示開關
想要將是否顯示改為快速開關
![mark](https://img-blog.csdnimg.cn/img_convert/e1c099071a01b64600fdec326f62bca2.png)
- 自定義列模板
1.通過 `Scoped slot` 可以獲取到 row, column, $index 和 store(table 內部的狀態管理)的資料
2.使用Switch開關
```vue
Scoped slot:https://element.eleme.cn/#/zh-CN/component/table
Switch開關:https://element.eleme.cn/#/zh-CN/component/switch
```
新增更新方法
```javascript
// 更新題目是否顯示
updateQuestionStatus(data) {
console.log(data)
let {id, enable} = data
this.$http({
url: this.$http.adornUrl('/question/question/update'),
method: 'post',
data: this.$http.adornData({id, enable}, false)
}).then(({ data }) => {
this.$message({
type:"success",
message: "狀態更新成功"
})
});
},
```
### 3.前端欄位校驗
對排序欄位限制:必須為正整數
```vue
dataRule: {
displayOrder: [
{
validator: (rule, value, callback) => {
if (value == "") {
callback(new Error("排序欄位必須填寫"));
} else if (!Number.isInteger(value) || value<0) {
callback(new Error("排序必須是一個大於等於0的整數"));
} else {
callback();
}
},
trigger: "blur"
}
]
}
```
### 4.後端欄位校驗
- 實體類欄位上添加註解`@Positive`必須是大於0的數字
```java
/**
* 排序
*/
@Positive
private Integer displayOrder;
```
- API 添加註解`@Valid`
```
/**
* 儲存
*/
@RequestMapping("/save")
public R save(@Valid @RequestBody QuestionEntity question){
questionService.save(question);
return R.ok();
}
```
測試結果
![後端欄位校驗](https://img-blog.csdnimg.cn/img_convert/4edf6f993615c4dc2bb94fbf90a2f335.png)
-1,0,0.2 不通過
測試1,1.2通過
### 5.模糊查詢題目列表
修改實現類`QuestionServiceImpl`的`queryPage`方法
**原方法**:
```java
public PageUtils queryPage(Map params) {
IPage page = this.page(
new Query().getPage(params),
new QueryWrapper()
);
return new PageUtils(page);
}
```
**修改後**:
```java
@Override
public PageUtils queryPage(Map params) {
//1.get key
String key = (String) params.get("key");
QueryWrapper queryWrapper = new QueryWrapper<>();
if (!StringUtils.isEmpty(key)) {
queryWrapper.eq("id", key).or().like("title", key).or().like("answer", key);
}
IPage page = this.page(
new Query().getPage(params),
queryWrapper
);
return new PageUtils(page);
}
```
### 6.新增分頁外掛
![沒有分頁外掛顯示共0條](https://img-blog.csdnimg.cn/img_convert/259b67e5397155f8b17c5986dc1bd845.png)
新增分頁外掛
```java
package com.jackson0714.passjava.question.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement //開啟事務
@MapperScan("com.jackson0714.passjava.question.dao")
public class MyBatisConfig {
//引入分頁外掛
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 設定請求的頁面大於最大頁後操作, true調回到首頁,false 繼續請求 預設false
paginationInterceptor.setOverflow(true);
// 設定最大單頁限制數量,預設 500 條,-1 不受限制
paginationInterceptor.setLimit(1000);
return paginationInterceptor;
}
}
```
新增分頁外掛後的顯示
![配置了分頁外掛的顯示](https://img-blog.csdnimg.cn/img_convert/999c76484f1d24f785726418aa8d4a2a.png)
# 六、PassJava 高階實踐篇
## 6.1 Spring Cloud Alibaba 元件簡介
### 1.SpringCloud Alibaba概述
> Spring Cloud Alibaba 致力於提供微服務開發的一站式解決方案。此專案包含開發分散式應用微服務的必需元件,方便開發者通過 Spring Cloud 程式設計模型輕鬆使用這些元件來開發分散式應用服務。
>
> 依託 Spring Cloud Alibaba,您只需要新增一些註解和少量配置,就可以將 Spring Cloud 應用接入阿里微服務解決方案,通過阿里中介軟體來迅速搭建分散式應用系統。
Github:https://github.com/alibaba/spring-cloud-alibaba
**Spring Cloud的幾大痛點**
- 部分元件停止維護和更新,有問題也不易解決
- 部分環境搭建起來比較複雜,沒有非常友好的視覺化介面
- 配置相對來說複雜,需要較高的學習成本
**Spring Cloud Alibaba的優勢**
- 阿里經歷過了時間的考驗
- 設計合理
- 擁有不錯的視覺化介面,方便運維監控和排查問題
- 環境搭建和配置簡單,學習成本低
**PassJava專案搭配SpringCloud Alibaba技術的搭配方案**
| 描述 | Spring Cloud | Spring Cloud Alibaba | 組合選用 |
| ------------ | ------------------------------ | -------------------- | ------------------------------- |
| 服務發現元件 | Eureka(停止維護)服務發現元件 | Nacos 註冊中心 | Spring Cloud Alibaba - Nacos |
| 配置中心元件 | Spring Cloud Config 配置中心 | Nacos 配置中心 | Spring Cloud Alibaba - Nacos |
| 斷路保護元件 | Hystrix 斷路保護 | Sentinel 服務容錯 | Spring Cloud Alibaba - Sentinel |
| 鏈路追蹤元件 | Sleuth 呼叫鏈監控 | / | Spring Cloud - Sleuth |
| 負載均衡元件 | Ribbon | / | Spring Cloud - Ribbon |
| 遠端呼叫元件 | OpenFeign (HTTP+JSON) | Dubbo(RPC框架) | Spring Cloud - OpenFeign |
| 分散式事務 | / | Seata 分散式事務 | Spring Cloud Alibaba - Seata |
| API 閘道器 | Gateway | / | Spring Cloud - Gateway |
**最後技術選型:**
```json
Spring Cloud Alibaba - Nacos 實現註冊中心
Spring Cloud Alibaba - Nacos 實現配置中心
Spring Cloud Alibaba - Sentinel 實現服務容錯
Spring Cloud Alibaba - Seata 實現分散式事務
Spring Cloud - Ribbon 實現負載均衡
Spring Cloud - Feign 實現遠端呼叫
Spring Cloud - Gateway API閘道器
Spring Cloud - Sleuth 實現呼叫鏈監控
```
### 2.Spring Cloud Alibaba版本
專案的版本號格式為 x.x.x 的形式,其中 x 的數值型別為數字,從 0 開始取值,且不限於 0~9 這個範圍。專案處於孵化器階段時,第一位版本號固定使用 0,即版本號為 0.x.x 的格式。
由於 Spring Boot 1 和 Spring Boot 2 在 Actuator 模組的介面和註解有很大的變更,且 spring-cloud-commons 從 1.x.x 版本升級到 2.0.0 版本也有較大的變更,因此阿里採取跟 SpringBoot 版本號一致的版本:
- 1.5.x 版本適用於 Spring Boot 1.5.x
- 2.0.x 版本適用於 Spring Boot 2.0.x
- 2.1.x 版本適用於 Spring Boot 2.1.x
- 2.2.x 版本適用於 Spring Boot 2.2.x
Spring Cloud Alibaba 版本和Spring Cloud 和Spring Boot 版本相容性列表
| Spring Cloud 版本 | Spring Cloud Alibaba 版本 | Spring Boot 版本 |
| ----------------------- | ------------------------- | ---------------- |
| Spring Cloud Hoxton.SR3 | 2.2.x.RELEASE | 2.2.x.RELEASE |
| Spring Cloud Greenwich | 2.1.x.RELEASE | 2.1.x.RELEASE |
| Spring Cloud Finchley | 2.0.x.RELEASE | 2.0.x.RELEASE |
| Spring Cloud Edgware | 1.5.x.RELEASE | 1.5.x.RELEASE |
我們採用`Spring Cloud Hoxton.SR3`, `Spring Cloud Alibaba 2.2.0.RELEASE`, `Spring Boot 2.2.6 RELEASE`
PassJava-Common的pom.xml檔案引入Spring Cloud Alibaba依賴
```xml
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2.2.0.RELEASE
pom
import
```
## 6.2 SpringCloud整合Alibaba-Nacos元件
> [Nacos](https://github.com/alibaba/Nacos) 是阿里巴巴開源的一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平臺。
### 1.引入Nacos 服務發現元件
passjava-common模組的pom.xml檔案引入Nacos 服務發現元件
```xml
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
```
### 2.下載Nacos Server並啟動
- 下載Nacos Server 壓縮包
https://github.com/alibaba/nacos/releases
啟動 Server,進入解壓後文件夾或編譯打包好的資料夾,找到如下相對資料夾 nacos/bin,並對照作業系統實際情況之下如下命令。
1. Linux/Unix/Mac 作業系統,執行命令 `sh startup.sh -m standalone`
2. Windows 作業系統,執行命令 `cmd startup.cmd`
windows執行startupm.cmd遇到問題:
```
λ startup.cmd
Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better!
```
解決方案:
修改startup.cmd檔案中的%JAVA_HOME%
```sh
%JAVA_HOME% 替換為 C:\Program Files\Java\jdk1.8.0_131
```
啟動成功:
### 3.每個微服務都配置Nacos Server 地址
- 配置Nacos Server 地址
在passjava-question、passjava-channel、passjava-content、passjava-member、passjava-study 應用的 /src/main/resources/application.yml配置檔案中配置 Nacos Server 地址
```yaml
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
```
### 4.添加註解
為每個服務使用 @EnableDiscoveryClient 註解開啟服務註冊與發現功能
```java
@EnableDiscoveryClient
@MapperScan("com.jackson0714.passjava.question.dao")
@SpringBootApplication
public class PassjavaQuestionApplication {
public static void main(String[] args) {
Spring