SpringCloud Alibaba
簡介和緣由
SpringCloud 的幾大痛點
SpringCloud 部分元件停止維護和更新,給開發帶來不便;比如eureka停止運維
SpringCloud 部分環境搭建複雜,沒有完善的可視化界面,我們需要大量的二次開發和定制
SpringCloud 配置複雜,難以上手,部配置設定置差别難以區分和合理應用
SpringCloud Alibaba 的優勢:
阿裡使用過的元件經曆了考驗,性能強悍,設計合理,現在開源出來大家用
成套的産品搭配完善的可視化界面給開發運維帶來極大的便利
搭建簡單,學習曲線低。
結合 SpringCloud Alibaba 我們最終的技術搭配方案:
SpringCloud Alibaba - Nacos:注冊中心(服務發現/注冊)
SpringCloud Alibaba - Nacos:配置中心(動态配置管理)
SpringCloud - Ribbon:負載均衡
SpringCloud - Feign:聲明式 HTTP 用戶端(調用遠端服務)
SpringCloud Alibaba - Sentinel:服務容錯(限流、降級、熔斷)
SpringCloud - Gateway:API 網關(webflux 程式設計模式)
SpringCloud - Sleuth:調用鍊監控
SpringCloud Alibaba -
版本選擇
由于 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
項目中導入依賴
參考官網
在 common 項目中引入如下。進行統一管理
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
SpringCloud Alibaba-Nacos作為注冊中心
參考官網
首先,修改 pom.xml 檔案,引入 Nacos Discovery Starter。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
然後在應用的 /src/main/resources/application.properties 配置檔案中配置 Nacos Server 位址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
使用 @EnableDiscoveryClient 注解開啟服務注冊與發現功能
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication
{
public static void main(String[] args)
{
SpringApplication.run(ProviderApplication.class, args);
}
@RestController
class EchoController
{
@GetMapping(value = "/echo/{string}")
public String echo(@PathVariable String string)
{
return string;
}
}
}
最後還需要給應用起一個名字才能注冊到服務中心
spring:
datasource:
username: root
password: 123
url: jdbc:mysql://10.235.140.206:3306/gulimall_oms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.jdbc.Driver
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: coupon
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type:
feign 遠端調用
注冊剩下的服務上去,然後使用open-feign進行服務之間的遠端調用
Feign 聲明式遠端調用
簡介
Feign 是一個聲明式的 HTTP 用戶端,它的目的就是讓遠端調用更加簡單。Feign 提供了 HTTP
請求的模闆,通過編寫簡單的接口和插入注解,就可以定義好 HTTP 請求的參數、格式、地
址等資訊。
Feign 整合了 Ribbon(負載均衡)和 Hystrix(服務熔斷),可以讓我們不再需要顯式地使用這
兩個元件。
SpringCloudFeign 在 NetflixFeign 的基礎上擴充了對 SpringMVC 注解的支援,在其實作下,我
們隻需建立一個接口并用注解的方式來配置它,即可完成對服務提供方的接口綁定。簡化了
SpringCloudRibbon 自行封裝服務調用用戶端的開發量。
使用
1、引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
我出現這樣的錯誤
2、開啟 feign 功能
package com.jane.shop.member;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* 遠端調用服務的步驟:
* 1.首先得引入openfeign
* 2.編寫一個接口,告訴spring cloud這個接口需要調用的遠端服務
* 接口裡面聲明的方法都是調用哪個遠端服務的哪個請求
* 3.開啟遠端調用功能,裡面的basePackages說明遠端調用的接口在哪裡
*/
@EnableFeignClients(basePackages = "com.jane.shop.member.feign")
@SpringBootApplication
@EnableDiscoveryClient
public class MemberApplication
{
public static void main(String[] args)
{
SpringApplication.run(MemberApplication.class, args);
}
}
3、聲明遠端接口
package com.jane.shop.member.feign;
import com.jane.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author jane
* @create 2021-03-03 15:05
* 首先得@FeignClient("coupon")聲明這是個遠端用戶端,裡面寫在注冊中心注冊的服務名
* 然後再接口裡面寫對應這個服務提供服務的抽象方法,路徑要寫完整的路徑
*/
@FeignClient("coupon")
public interface CouponFeignService
{
@RequestMapping("/coupon/coupon/member/list")
public R membercoupon();
}
SpringCloud Alibaba-Nacos作為配置中心
參考官網
/**
* 1、如何使用Nacos作為配置中心統一管理配置
*
* 1)、引入依賴,
* <dependency>
* <groupId>com.alibaba.cloud</groupId>
* <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
* </dependency>
* 2)、建立一個bootstrap.properties。
* spring.application.name=coupon
* spring.cloud.nacos.config.server-addr=127.0.0.1:8848
* 3)、需要給配置中心預設添加一個叫 資料集(Data Id)coupon.properties。預設規則,應用名.properties
* 4)、給 應用名.properties 添加任何配置
* 5)、動态擷取配置。
* @RefreshScope:動态擷取并重新整理配置
* @Value("${配置項的名}"):擷取到配置。
* 如果配置中心和目前應用的配置檔案中都配置了相同的項,優先使用配置中心的配置。
*/
這裡我暫時是有bug,解決不了
我出現的bug
配置中心的細節
命名空間
用來做配置隔離的,預設使用的是public(保留白間)
預設新增的所有配置都在public空間。
比如我們有開發環境,測試環境,生産環境:利用命名空間來做環境隔離。
注意:在bootstrap.properties;配置上,需要說明使用哪個命名空間下的配置,
spring.cloud.nacos.config.namespace=69c39f7b-107c-4995-b0b3-643ff4a392ff
比如我們每個微服務都有自己的配置,配置檔案衆多,
配置集
所有的配置的集合
配置集ID
配置集ID:類似檔案名。
Data ID:類似檔案名
配置分組
預設所有的配置集都屬于:DEFAULT_GROUP;
比如雙十一使用111,
還有其他的節日活動:618,1212
然後需要在配置檔案裡面配置(DEFAULT_GROUP就是對應的組名)
spring.cloud.nacos.config.group=DEFAULT_GROUP
然後現在我們想的是:
同時加載多個配置集
1)、微服務任何配置資訊,任何配置檔案都可以放在配置中心中
2)、隻需要在bootstrap.properties說明加載配置中心中哪些配置檔案即可
3)、@Value,@ConfigurationProperties。。。
以前SpringBoot任何方法從配置檔案中擷取值,都能使用。
配置中心有的優先使用配置中心中的,
比如現在我們按照資料庫的配置,mybatis的配置,和其他配置的分類
将配置分類,然後再在bootstrap.properties進行說明
spring.cloud.nacos.config.ext-config[0].data-id=datasource.yml
spring.cloud.nacos.config.ext-config[0].group=dev
spring.cloud.nacos.config.ext-config[0].refresh=true
spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yml
spring.cloud.nacos.config.ext-config[1].group=dev
spring.cloud.nacos.config.ext-config[1].refresh=true
spring.cloud.nacos.config.ext-config[2].data-id=other.yml
spring.cloud.nacos.config.ext-config[2].group=dev
spring.cloud.nacos.config.ext-config[2].refresh=true
spring cloud的gateway網關
動态上下線:
發送請求需要知道商品服務的位址,如果商品伺服器有123伺服器,1号掉線後,還得改,
是以需要網關動态地管理,他能從注冊中心中實時地感覺某個服務上線還是下線。
【先通過網關,網關路由到服務提供者】
攔截:請求也要加上詢問權限,看使用者有沒有權限通路這個請求,也需要網關。
是以我們使用spring cloud的gateway元件做網關功能。
網關是請求流量的入口,常用功能包括路由轉發,權限校驗,限流控制等。
springcloud gateway取代了zuul網關。
官方文檔
三大核心概念
Route:
The basic building block of the gateway.
It is defined by an ID, a destination URI, a collection of predicates,
and a collection of filters.
A route is matched if the aggregate predicate is true.
發一個請求給網關,網關要将請求路由到指定的服務。
路由有id,目的地uri,斷言的集合,比對了斷言就能到達指定位置,
Predicate斷言:
This is a Java 8 Function Predicate.
The input type is a Spring Framework ServerWebExchange.
This lets you match on anything from the HTTP request,
such as headers or parameters.
就是java裡的斷言函數,比對請求裡的任何資訊,包括請求頭等。根據請求頭路由哪個服務
Filter:
These are instances of Spring Framework GatewayFilter that have been
constructed with a specific factory.
Here, you can modify requests and responses before or after
sending the downstream request.
用戶端發請求給服務端。中間有網關。先交給映射器,
如果能處理就交給handler處理,然後交給一系列filer,
然後給指定的服務,再傳回回來給用戶端。
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
比如上面的斷言,-代表數組,後面還可以寫很多的斷言
The After route predicate factory takes one parameter,
a datetime (which is a java ZonedDateTime).
This predicate matches requests that happen after the specified datetime.
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red,
The AddRequestHeader GatewayFilter factory takes a name and value parameter.
The following example configures an AddRequestHeader GatewayFilter
這個過濾器沒有斷言,是以所有的請求都會來到這裡,然後路由到uri去
但是經過這個過濾器的都會在請求頭加上X-Request-red :
建立網關
建立,使用initilizer,
Group:com.jane.shop,
Artifact: gateway,
package:com.jane.shop.gateway。
搜尋gateway選中。
pom.xml裡加上common依賴, 修改jdk版本,
開啟注冊服務發現@EnableDiscoveryClient
配置nacos注冊中心位址applicaion.properties
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.application.name=gateway
server.port=88
bootstrap.properties 填寫nacos配置中心位址
在nacos配置好相應的配置
spring.application.name=gateway
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=48b8175f-ceab-40f4-9042-899f966e6858
spring.cloud.nacos.config.group=dev
在項目裡建立application.yml,根據條件轉發到uri等
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
The preceding route matches if the request contained a red query parameter
whose value matched the gree. regexp, so green and greet would match.
根據官網,這是比對請求中帶有參數red,并且參數的值是gree的正規表達式
下面我們寫成這樣測試去百度行不行
spring:
cloud:
gateway:
routes:
- id: test_route
uri: https://www.baidu.com
predicates:
- Query=url,baidu