版本選擇
Spring Boot、Spring Cloud、Spring Coud Alibaba版本選擇官網: 版本說明
項目搭建
- 創建父POM項目
File -> new Project -> maven -> Next
刪除不需要的文件(因為是父POM、只要剩下POM文件就行了、MD文件后續再補)
- 統一版本管理
<!--統一管理Jar的版本-->
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring.cloud.alibaba-version>2021.1</spring.cloud.alibaba-version>
<spring.cloud-version>2020.0.1</spring.cloud-version>
<spring.boot.version>2.4.2</spring.boot.version>
<lombok.version>1.18.16</lombok.version>
<hutool.version>5.7.19</hutool.version>
<fastjson.version>1.2.75</fastjson.version>
<druid.version>1.1.22</druid.version>
<mysql.version>8.0.23</mysql.version>
<mybatis.plus.version>3.4.2</mybatis.plus.version>
</properties>
- 鎖定子模塊版本
<!--在dependencyManagement元素中聲明所依賴的jar包的版本號等信息,那么所有子項目再次引入此依賴jar包時則無需顯式的列出版本號。
Maven會沿著父子層級向上尋找擁有dependencyManagement 元素的項目,然后使用它指定的版本號。-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 通用依賴引入
<dependencies>
<!--mybatis plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis.plus.version}</version>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
<scope>runtime</scope>
</dependency>
<!-- 實現對數據庫連接池的自動化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--mybatis plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis.plus.version}</version>
</dependency>
<!-- 連接池 阿里巴巴數據源 全世界最牛逼的data source 沒有之一 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!--Lombok項目是一個Java庫,它會自動插入編輯器和構建工具中,Lombok提供了一組有用的注釋,用來消除Java類中的大量樣板代碼-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!--Hutool是一個小而全的Java工具類庫,通過靜態方法封裝,降低相關API的學習成本,提高工作效率,使Java擁有函數式語言般的優雅,讓Java語言也可以“甜甜的”。-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<!-- fastjson json轉換 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
</dependencies>
子模塊創建(服務提供者)
- 創建子模塊
- 修改POM
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--服務注冊-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!--配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--2021以上版本需要引入該jar才能使bootstrap配置文件生效-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--RPC框架-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--spring監控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
- 編寫主啟動類 src/main/java
com.cloud.pay.PayMain8001
package com.cloud.pay;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 功能描述:支付模塊主啟動類
*
* @Author: zhuheguo
* @Date: 2022/4/11 10:30
*/
@SpringBootApplication
@EnableDiscoveryClient
@RestController
@RefreshScope
@EnableFeignClients
public class PayMain8001 {
public static void main(String[] args) {
SpringApplication.run(PayMain8001.class, args);
}
@Value("${test}")
private String test;
@GetMapping("test")
public String test() {
return test + "\thello world!";
}
}
- 編寫配置文件 src/main/resource
bootstrap.yml
(使用properties也可以ToYaml)
management:
endpoints:
web:
exposure:
include: '*'
spring:
application:
name: cloud-pay
cloud:
nacos:
config:
file-extension: yaml
group: DEFAULT_GROUP
namespace: cloud-demo
server-addr: tx.ovozz.com:8848
profiles:
active: dev
- 配置Nacos(配置中心和服務注冊中心)
Nacos官方文檔:https://github.com/alibaba/Nacos
1.創建命名空間
2.編寫配置文件
server:
port: 8001
test: 'test nacos config!'
spring:
cloud:
nacos:
discovery:
namespace: cloud-demo
server-addr: tx.ovozz.com:8848
# datasource 數據源配置內容,對應 DataSourceProperties 配置屬性類
datasource:
#druid監控地址http://localhost:${server.port}/druid/login.html
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://tx.ovozz.com:3306/cloud_demo?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
username: cloud_demo
password: cloud_demo
# 初始化配置
initial-size: 3
# 最小連接數
min-idle: 3
# 最大連接數
max-active: 15
# 獲取連接超時時間
max-wait: 5000
# 連接有效性檢測時間
time-between-eviction-runs-millis: 90000
# 最大空閑時間
min-evictable-idle-time-millis: 1800000
test-while-idle: true
test-on-borrow: false
test-on-return: false
validation-query: select 1
# 配置監控統計攔截的filters
filters: stat,wall,log4j,config
stat-view-servlet:
url-pattern: /druid/*
reset-enable: false
- 啟動與測試
PS: 啟動前創建數據庫操作就不演示了
-
啟動支付服務模塊
main -> debug -
測試接口訪問和獲取Nacos Config 配置 http://localhost:8001/test
官方文檔:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
http://localhost:8001/test 修改Nacos 中的配置文件
cloud-pay-dev.yaml
發布并且刷新頁面http://localhost:8001/test
- 服務注冊
在Nacos管理 -> 服務管理 -> 服務列表中看到 cloud-pay 則代表服務注冊成功
子模塊創建(服務消費者)
創建流程同上
項目右鍵 -> New -> Module -> Maven -> Next -> cloud-pay-consumer-9001 -> Finish
copy pom
copy bootstrap.yml
并修改項目名稱(服務名稱),其它的都一樣
spring:
application:
name: cloud-pay-consumer
- Nacos 中添加配置文件
cloud-pay-consumer-dev.yaml
其實就是copy了之前的修改了端口
server:
port: 9001
#省略了其它相同的文件
- 編寫主啟動類
com.cloud.pay.PayConsumerMain9001
package com.cloud.pay;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* 功能描述:支付模塊消費者主啟動類
*
* @Author: zhuheguo
* @Date: 2022/4/11 10:30
*/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class PayConsumerMain9001 {
public static void main(String[] args) {
SpringApplication.run(PayConsumerMain9001.class, args);
}
}
- 編寫接口 com.cloud.pay.service.PayService
package com.cloud.pay.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
/**
* 功能描述:
*
* @Author: zhuheguo
* @Date: 2022/4/11 15:13
*/
@FeignClient("cloud-pay")
public interface PayService {
/**
* 測試支付消費接口
* @return
*/
@GetMapping("test")
String pay();
}
- 啟動與測試
- 測試負載均衡
修改PayMain8001
@Value("${test}")
private String test;
@Value("${server.port}")
private String port;
@GetMapping("test")
public String test() {
return test + ":" + port + "\thello world!";
}
利用8001修改端口啟動8002 (不會可以參考 Idea中一個服務按多個端口同時啟動)
把8001啟動配置也加上-Dserver.port=8001
把Nacos 中配置中心的cloud-pay-dev.yaml
文件刪除端口配置
server:
port: 8001
啟動idea中的8001和8002
反復刷新http://localhost:9001/pay
測試 sentinel
- 項目配置
官方文檔:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
在```cloud-pay-8001``項目的pom中添加
<!--Sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--sentinel 持久化-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
在Nacos管理頁 -> 配置管理 -> 配置列表 -> cloud-demo -> cloud-pay-dev.yaml 添加
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
port: 8719
- 測試監控
啟動8001和Sentinel控制臺(https://github.com/alibaba/Sentinel/releases 下載然后jar運行默認8080端口)
訪問http://localhost:8080并登錄
登錄進去默認什么都沒有,然后我們瘋狂刷新http://localhost:8001/test然后所在次刷新http://localhost:8080
- 測試流控(服務熔斷)
QPS:每秒查詢率(QPS,Queries-per-second)是對一個特定的查詢服務器在規定時間內所處理流量多少的衡量標準。
新增后嘗試每隔一秒訪問一次和瘋狂訪問http://localhost:8001/test可以看出這個規則限定每秒只能訪問一次,規則范圍為的被Sentinel限流了
- 測試降級(服務熔斷)
在PayMain8001添加接口并重啟
@GetMapping("/testA")
public String testA(@RequestParam int num) {
return "testA---:" + (1 / num);
}
為了演示,選擇最簡單的異常數來測試熔斷機制
訪問http://localhost:8001/testA?num=1進行測試,發現無論如何不會觸發熔斷
訪問http://localhost:8001/testA?num=0進行測試,發現每秒請求數超過5次并且異常數達到兩次則熔斷20秒
其它控制臺配置請自行查閱資料了解
@SentinelResource 請參考https://blog.csdn.net/weixin_41213402/article/details/105511219
分布式事務
配置太多了,單獨的文章有介紹http://www.lxweimin.com/p/d08ee4567749
服務網關
打包發布
需要打包的項目POM中添加打包插件即可,可以參考http://www.lxweimin.com/p/edf18c93236b
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
開源地址
https://gitee.com/zhuheguo/cloud-demo.git
踩坑記錄
- 基于SpringBoot bootstrap.yml配置未生效的解決
作者一開始使用Spring Boot項目升級到Spring Cloud項目使用Nacos Config一直不生效,困擾了我整整一天,一直排查Nacos的問題,最后發現是因為 bootstrap.yml不生效(懷疑人生)
解決方案:引入spring-cloud-starter-bootstrap
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
- 控制臺拋出異常
nested exception is java.lang.IllegalStateException: No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalancer
解決方案:Spring Cloud [Feign]在Hoxton.M2 RELEASED版本之后不再使用Ribbon而是使用spring-cloud-loadbalancer
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>