1. 程式人生 > >5w 字 | 172 圖 | 超級賽亞級 Spring Cloud 實戰

5w 字 | 172 圖 | 超級賽亞級 Spring Cloud 實戰

# 一、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