天天看點

【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway

文章目錄

  • 1 Nacos
    • 1.0安裝
    • 1.1注冊中心
    • 1.2配置中心
  • 2 spring-cloud-openfeign
  • 3 spring-cloud-gateway

Spring Cloud官方 link + Github link

【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway

這裡gulimall-common這是一個公共子產品maven工程(添加共有依賴),别的幾個都是springboot工程提供微服務

依賴管理:相當于以後再dependencies裡引spring cloud alibaba、spring cloud就不用寫版本号

spring cloud alibaba:在pom中dependencyManagement 中添加如下配置。然後在 dependencies 中添加自己所需使用的依賴即可使用。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
           

spring cloud alibaba與spring boot的版本對應

【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway

Spring Cloud相關微服務時是的dependencyManagement

<properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
    </properties>
    
    <dependencyManagement>
        <dependencies>
            <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>
           

1 Nacos

1.0安裝

下載下傳github的release檔案工具:link

驗證是否啟動成功的網址:http://localhost:8848/nacos/index.html

使用者名預設:nacos,密碼:nacos

【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway
【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway

之前遇到這麼個問題

【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway

startup.sh中将JAVA_HOME修改為jdk的路徑,下面三行屏蔽

【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway
【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway

1.1注冊中心

1.首先,修改 pom.xml 檔案,引入 Nacos Discovery Starter。

<dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 </dependency>
           

2.在應用的 /src/main/resources/application.yml 配置檔案中配置 Nacos Server 應用名稱和位址 PS:就統一不在application.properties裡配置了,一樣的。

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  application:
    name: gulimall-product
           

3.使用 @EnableDiscoveryClient 注解開啟服務注冊與發現功能

@MapperScan("com.atguigu.gulimall.product.dao") //掃描Dao操作的@Mapper加入IOC
@SpringBootApplication 
@EnableDiscoveryClient //注冊
@EnableFeignClients(basePackages = "com.atguigu.gulimall.product.feign") //使能遠端調用Feign
public class GulimallProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(GulimallProductApplication.class, args);
    }
}
           

務必保證所有服務都注冊到Nacos(公共子產品gulimall-common就算了),否則無法遠端調用和進行網關lb(load balance)

1.2配置中心

1.首先,修改 pom.xml 檔案,引入 Nacos Config Starter。

<dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 </dependency>
           

2.在應用的 /src/main/resources/bootstrap.properties 配置檔案中配置 Nacos Config 中繼資料

spring.application.name=gulimall-product
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

spring.cloud.nacos.config.namespace=0033369e-90ec-4da9-9db7-6e9db55f50da #指定命名空間,預設為public
spring.cloud.nacos.config.group=prod #指定分組
spring.cloud.nacos.config.refresh-enabled=true #更改配置後自動重新整理,不用重新開機應用

#多個配置檔案方式
#spring.cloud.nacos.config.extension-configs[0].data-id=oss.yml
#spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP
#spring.cloud.nacos.config.extension-configs[0].refresh=true
#spring.cloud.nacos.config.extension-configs[1].data-id=xxx.yml
#spring.cloud.nacos.config.extension-configs[1].group=dev
#spring.cloud.nacos.config.extension-configs[1].refresh=true
           

3.完成上述兩步後,應用會從 Nacos Config 中擷取相應的配置,并添加在 Spring Environment 的 Property Sources 中

4.動态擷取配置。@RefreshScope:動态擷取并重新整理配置,這裡我們使用 @Value("${配置項的名}")注解來将對應的配置注入到字段

(如果配置中心和目前應用的配置檔案中都配置了相同的項,優先使用配置中心的配置。)

@RefreshScope
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
 	@Value("${coupon.user.name}")
    private String name;
    @Value("${coupon.user.age}")
    private Integer age;
    ....
}
           

Nacos作為配置中心時:紅框中建立命名空間,籃框+建立配置檔案(可指定分組)

【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway

PS:項目中的使用:每個微服務建立自己的命名空間,使用配置分組區分環境,dev,test,prod

2 spring-cloud-openfeign

feign是一個聲明式的HTTP用戶端,他的目的就是讓遠端調用更加簡單。給遠端服務發的是HTTP請求。

想要遠端調用的步驟:

1 在pom中引入openfeign(需要spring cloud的依賴管理)

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
           

2 編寫一個接口,接口告訴springcloud這個接口需要調用遠端服務

  • 2.1 在接口裡聲明@FeignClient(“gulimall-coupon”)他是一個遠端調用用戶端且要調用coupon服務
@FeignClient("gulimall-coupon")
public interface CouponFeignService { //注意這個是接口
    /**
     * 1、CouponFeignService.saveSpuBounds(spuBoundTo);
     *      1)、@RequestBody将這個對象轉為json。
     *      2)、找到gulimall-coupon服務,給/coupon/spubounds/save發送請求。
     *          将上一步轉的json放在請求體位置,發送請求;
     *      3)、對方服務收到請求。請求體裡有json資料。
     *          (@RequestBody SpuBoundsEntity spuBounds);将請求體的json轉為SpuBoundsEntity;
     * 隻要json資料模型是相容的。雙方服務無需使用同一個to
     * @param spuBoundTo
     * @return
     */
    @PostMapping("/coupon/spubounds/save")  //直接讓背景指定服務處理  
    //讓所有請求過網關則 @PostMapping("/api/coupon/spubounds/save")
    R saveSpuBounds(@RequestBody SpuBoundTo spuBoundTo);


    @PostMapping("/coupon/skufullreduction/saveinfo")
    R saveSkuReduction(@RequestBody SkuReductionTo skuReductionTo);
}
           
  • 2.2 要調用coupon服務的/coupon/spubounds/save和/coupon/skufullreduction/saveinfo方法
//  /coupon/spubounds/save
    @PostMapping("/save")
    //@RequiresPermissions("coupon:spubounds:save")
    public R save(@RequestBody SpuBoundsEntity spuBounds){
		spuBoundsService.save(spuBounds);
        return R.ok();
    }
    
// /coupon/skufullreduction/saveinfo
    @PostMapping("/saveinfo")
    public R saveInfo(@RequestBody SkuReductionTo reductionTo){

        skuFullReductionService.saveSkuReduction(reductionTo);
        return R.ok();
    }
           

3 開啟遠端調用功能 @EnableFeignClients,要指定遠端調用功能放的基礎包

@EnableFeignClients(basePackages = "com.atguigu.gulimall.product.feign")
@EnableDiscoveryClient
@MapperScan("com.atguigu.gulimall.product.dao")
@SpringBootApplication
public class GulimallProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(GulimallProductApplication.class, args);
    }
}
           

4 本服務如何遠端調用

@Autowired 
    CouponFeignService couponFeignService; //注入
    
	R r = couponFeignService.saveSpuBounds(spuBoundTo);
    if (r.getCode() != 0) {
        log.error("遠端儲存spu積分失敗");
    }

           

3 spring-cloud-gateway

三大核心概念:

  • 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.過濾器請求和響應都可以被修改。
    【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway
    在pom中配置依賴(需要spring cloud的依賴管理):
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
           

注:隻有服務注冊了,才可以通過網關發現該服務,同時網關服務也需要注冊進Nacos

在application.yml中進行網關的路由配置的時候,是有順序的,小範圍的predicates在前面,要不會被攔截走

spring:
  cloud:
    gateway:
      routes:
        - id: product_route
          uri: lb://gulimall-product # lb(load balance)代表從注冊中心擷取注冊名為gulimall-product服務 
          predicates:
            - Path=/api/product/**
          filters:
            - RewritePath=/api/(?<segment>.*),/$\{segment} #即去掉/api

        - id: admin_route
          uri: lb://renren-fast
          predicates:
            - Path=/api/**
          filters:
            - RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}
           

在啟動gulimall-gateway服務時,問題如下:

【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway

問題分析:由于公共依賴中有mybatis-plus配置(需要相應的datasource),而網關不需要mybatis-plus,是以啟動時得手動排除下

方式二:

在pom中給依賴給排除下

<dependency>
            <groupId>com.atguigu.gulimall</groupId>
            <artifactId>gulimall-common</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
           

起初我用的是6666端口啟動的,然而。。。看樣沒法飛起了

【Gulimall】Spring Cloud:spring-cloud-gateway、spring-cloud-openfeign,Alibaba的注冊+配置中心Nacos1 Nacos2 spring-cloud-openfeign3 spring-cloud-gateway

SOLVE:application.yml中換個端口

server:
  port: 6060
           

注意網關的pom中别引入start-web依賴,要不會引起下面的錯誤.

**************************
APPLICATION FAILED TO START
***************************
 
Description:
 
Parameter 0 of method modifyRequestBodyGatewayFilterFactory in org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' that could not be found.
 
 
Action:
 
Consider defining a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' in your configuration.
           

繼續閱讀