SpringCloud系列

SpringCloud系列

以下內容,均在搭建 lemon 項目時,收集和寫下的一些內容,如有錯誤歡迎指正>>>

實際中應用及推薦文章

推薦文章:https://blog.csdn.net/zrl0506/article/details/80165477

推薦文章:https://blog.csdn.net/qq_37170583/article/details/80704904

SpringCloud和SpringBoot對應版本

官方文檔:http://spring.io/projects/spring-cloud(一切始於官方文檔)

Table1

SpringCloud SpringBoot
Greenwich 2.1.X
Finchley 2.0.X
Edgware 1.5.x
Dalston 1.5.x

Table2

Component Edgware.SR5 Finchley.SR2 Finchley.BUILD-SNAPSHOT
spring-cloud-aws 1.2.3.RELEASE 2.0.1.RELEASE 2.0.1.BUILD-SNAPSHOT
spring-cloud-bus 1.3.3.RELEASE 2.0.0.RELEASE 2.0.1.BUILD-SNAPSHOT
spring-cloud-cli 1.4.1.RELEASE 2.0.0.RELEASE 2.0.1.BUILD-SNAPSHOT
spring-cloud-commons 1.3.5.RELEASE 2.0.2.RELEASE 2.0.2.BUILD-SNAPSHOT
spring-cloud-contract 1.2.6.RELEASE 2.0.2.RELEASE 2.0.2.BUILD-SNAPSHOT
spring-cloud-config 1.4.5.RELEASE 2.0.2.RELEASE 2.0.2.BUILD-SNAPSHOT
spring-cloud-netflix 1.4.6.RELEASE 2.0.2.RELEASE 2.0.2.BUILD-SNAPSHOT
spring-cloud-security 1.2.3.RELEASE 2.0.1.RELEASE 2.0.1.BUILD-SNAPSHOT
spring-cloud-cloudfoundry 1.1.2.RELEASE 2.0.1.RELEASE 2.0.1.BUILD-SNAPSHOT
spring-cloud-consul 1.3.5.RELEASE 2.0.1.RELEASE 2.0.2.BUILD-SNAPSHOT
spring-cloud-sleuth 1.3.5.RELEASE 2.0.2.RELEASE 2.0.2.BUILD-SNAPSHOT
spring-cloud-stream Ditmars.SR4 Elmhurst.SR1 Elmhurst.BUILD-SNAPSHOT
spring-cloud-zookeeper 1.2.2.RELEASE 2.0.0.RELEASE 2.0.1.BUILD-SNAPSHOT
spring-boot 1.5.16.RELEASE 2.0.6.RELEASE 2.0.7.BUILD-SNAPSHOT
spring-cloud-task 1.2.3.RELEASE 2.0.0.RELEASE 2.0.1.BUILD-SNAPSHOT
spring-cloud-vault 1.1.2.RELEASE 2.0.2.RELEASE 2.0.2.BUILD-SNAPSHOT
spring-cloud-gateway 1.0.2.RELEASE 2.0.2.RELEASE 2.0.2.BUILD-SNAPSHOT
spring-cloud-openfeign 2.0.2.RELEASE 2.0.2.BUILD-SNAPSHOT
spring-cloud-function 1.0.1.RELEASE 1.0.0.RELEASE 1.0.1.BUILD-SNAPSHOT

注意:

SpringCloud 版本爲 Edgware 及以下,eureka包改爲:

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

SpringCloud 版本爲 Edgware 以上,eureka包改爲netflix:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

SpringCloudEureka

入門案例(一) Server與Client

入門案例(二)Server、Porvider與Consumer

項目整體結構:

在這裏插入圖片描述

eureka-server入門

一、導入jar
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>lemon-soa</artifactId>
    <packaging>jar</packaging>

    <name>spring-cloud-eureka-server</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <spring-cloud.version>Dalston.SR4</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
    </dependencies>

    <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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

二、建立啓動類
package com.lemon.eureka.server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @author sjp
 */
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaServerApplication.class, args);
	}

}
三、配置yml
server:
    port: 9001

eureka:
    instance:
        hostname: eureka-service
    client:
        # 不註冊自己
        register-with-eureka: false
        # 獲取服務
        fetch-registry: false
        # 註冊中心地址
        service-url:
            defaultZone: http://localhost:${server.port}/eureka/

四、訪問

http://localhost:9001/
在這裏插入圖片描述

eureka-api 入門

Tips:此部分屬於provider和consumer公用部分,所以單獨作爲一個模塊,打包成jar供provider和consumer使用

模塊結構

在這裏插入圖片描述

一、導入jar
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-api</artifactId>

</project>

二、建立相關類
package com.lemon.soa.api;

public interface VideoService {
   /**
    * 獲取視頻信息
    * @param videoId 視頻id
    * @return 視頻信息
    */
   double getVideo(long videoId);
}

eureka-provider入門

Tips: Eureka本身只區分server和client(client有provider和consumer),通過不同的配置來告知client,本身是provider還是consumer.

模塊結構

在這裏插入圖片描述

一、導入jar
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-provider</artifactId>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Dalston.SR4</spring-cloud.version>
    </properties>

    <dependencies>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--內部依賴-->
        <dependency>
            <groupId>com.lemon</groupId>
            <artifactId>eureka-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

    </dependencies>

    <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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

二、建立相關類

啓動類:

package com.lemon;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class EurekaProviderApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaProviderApplication.class, args);
	}

}

服務接口實現:

package com.lemon.api.impl;

import org.springframework.stereotype.Service;

import com.lemon.soa.api.VideoService;

/**
 * @author sjp
 * @date 2019/1/24
 **/
@Service
public class VideoServiceImpl implements VideoService {
   @Override
   public double getVideo(long videoId) {
      return Math.random();
   }
}

暴露服務:

package com.lemon.controller;

import com.lemon.soa.api.VideoService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class VideoController {

   @Resource
   private VideoService videoService;

   @RequestMapping(value = "/{videoId}", method = RequestMethod.GET)
   public Double getVideo(@PathVariable long videoId) {
      return videoService.getVideo(videoId);
   }
}
三、配置yml
server:
    port: 9002

spring:
    application:
        name: eureka-provider

eureka:
    instance:
        #使用ip進行註冊
        prefer-ip-address: true
    client:
        serviceUrl:
            defaultZone: http://localhost:9001/eureka/
四、訪問

http://localhost:9001/

在這裏插入圖片描述

eureka-consumer入門

模塊結構

在這裏插入圖片描述

一、導入jar
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-consumer</artifactId>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.12.RELEASE</version>
    </parent>

    <properties>
        <spring-cloud.version>Edgware.SR3</spring-cloud.version>
    </properties>

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

    <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>

</project>

二、建立相關類

啓動類:

package com.lemon.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * @author sjp
 * @date 2019/1/24
 **/
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaConsumerApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaConsumerApplication.class, args);
	}

	/**
	 * 啓用負載均衡,默認算法是輪詢
	 */
	@LoadBalanced
	@Bean
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}
}

調用服務:

package com.lemon.consumer.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

/**
 * @author sjp
 * @date 2019/1/24
 **/
@RestController
public class ConsumerController {

   @Resource
   private RestTemplate restTemplate;

   @RequestMapping("/")
   public Double index() {
        return restTemplate.getForObject("http://eureka-provider/1", Double.class);
   }
}
三、配置yml
server:
    port: 9003

spring:
    application:
        name: eureka-consumer
eureka:
    instance:
        # 使用IP註冊
        prefer-ip-address: true
    #註冊地址
    client:
        service-url:
            defaultZone: http://localhost:9001/eureka/
四、訪問

http://localhost:9001/

在這裏插入圖片描述

熟悉掌握

eureka-server配置詳解

參數名 默認值 備註
enable-self-preservation true 自我保護模式,當出現出現網絡分區、eureka在短時間內丟失過多客戶端時,會進入自我保護模式,即一個服務長時間沒有發送心跳,eureka 也不會將其刪除,默認爲true
eviction-interval-timer-in-ms 60000 eureka server清理無效節點的時間間隔,默認60000毫秒,即60秒
a-s-g-cache-expiry-timeout-ms 6000 緩存ASG信息的到期時間,單位爲毫秒,默認爲10 * 60 * 1000
a-s-g-query-timeout-ms 300 查詢AWS上ASG(自動縮放組)信息的超時值,單位爲毫秒,默認爲300
a-s-g-update-interval-ms 5 * 60 * 1000 從AWS上更新ASG信息的時間間隔,單位爲毫秒
a-w-s-access-id 獲取aws訪問的id,主要用於彈性ip綁定,此配置是用於aws上的
a-w-s-secret-key 獲取aws私有祕鑰,主要用於彈性ip綁定,此配置是用於aws上的
batch-replication false 表示集羣節點之間的複製是否爲了網絡效率而進行批處理
binding-strategy 獲取配置綁定EIP或Route53的策略
delta-retention-timer-interval-in-ms 30 * 1000 清理任務程序被喚醒的時間間隔,清理過期的增量信息,單位爲毫秒
disable-delta false 增量信息是否可以提供給客戶端看,默認爲false
disable-delta-for-remote-regions false 增量信息是否可以提供給客戶端或一些遠程地區
disable-transparent-fallback-to-other-region false 如果在遠程區域本地沒有實例運行,對於應用程序回退的舊行爲是否被禁用
e-i-p-bind-rebind-retries 3 獲取服務器嘗試綁定到候選的EIP的次數
e-i-p-binding-retry-interval-ms-when-unbound 1 * 60 * 1000 服務器檢查ip綁定的時間間隔,單位爲毫秒
e-i-p-binding-retry-interval-ms 5 * 60 * 1000 與上面的是同一作用,僅僅是穩定狀態檢查
enable-replicated-request-compression false 複製的數據在發送請求時是否被壓縮
g-zip-content-from-remote-region true eureka服務器中獲取的內容是否在遠程地區被壓縮,默認爲true
json-codec-name 如果沒有設置默認的編解碼器將使用全JSON編解碼器,獲取的是編碼器的類名稱
list-auto-scaling-groups-role-name ListAutoScalingGroups 用來描述從AWS第三賬戶的自動縮放組中的角色名稱
log-identity-headers true Eureka服務器是否應該登錄clientAuthHeaders
max-elements-in-peer-replication-pool 10000 複製池備份複製事件的最大數量
max-elements-in-status-replication-pool: 10000 可允許的狀態複製池備份複製事件的最大數量
max-idle-thread-age-in-minutes-for-peer-replication 10 狀態複製線程可以保持存活的空閒時間
min-threads-for-status-replication 1 被用於狀態複製的線程的最小數目
max-idle-thread-in-minutes-age-for-status-replication 15 複製線程可以保持存活的空閒時間,默認爲15分鐘
max-threads-for-peer-replication 20 獲取將被用於複製線程的最大數目
max-time-for-replication 30000 嘗試在丟棄複製事件之前進行復制的時間,默認爲30000毫秒
min-threads-for-peer-replication 5 獲取將被用於複製線程的最小數目
number-of-replication-retries 5 獲取集羣裏服務器嘗試複製數據的次數
peer-eureka-nodes-update-interval-ms 10 * 60 * 1000 集羣裏eureka節點的變化信息更新的時間間隔,單位爲毫秒
peer-eureka-status-refresh-time-interval-ms 30 * 1000 服務器節點的狀態信息被更新的時間間隔,單位爲毫秒
peer-node-connect-timeout-ms 200 連接對等節點服務器複製的超時的時間,單位爲毫秒
peer-node-read-timeout-ms 200 讀取對等節點服務器複製的超時的時間,單位爲毫秒
peer-node-total-connections 1000 獲取對等節點上http連接的總數
peer-node-connection-idle-timeout-seconds 30 http連接被清理之後服務器的空閒時間,默認爲30秒
peer-node-total-connections-per-host 500 獲取特定的對等節點上http連接的總數
prime-aws-replica-connections true 對集羣中服務器節點的連接是否應該準備
rate-limiter-enabled 限流是否應啓用或禁用,默認爲false
rate-limiter-burst-size 速率限制的burst size ,默認爲10,這裏用的是令牌桶算法
rate-limiter-full-fetch-average-rate 100 速率限制器用的是令牌桶算法,此配置指定平均執行請求速率,默認爲100
rate-limiter-privileged-clients 認證的客戶端列表,這裏是除了標準的eureka Java客戶端。
rate-limiter-registry-fetch-average-rate 500 速率限制器用的是令牌桶算法,此配置指定平均執行註冊請求速率,默認爲500
rate-limiter-throttle-standard-clients false 是否對標準客戶端進行限流,默認false
registry-sync-retries 5 當eureka服務器啓動時嘗試去獲取集羣裏其他服務器上的註冊信息的次數,默認爲5
registry-sync-retry-wait-ms 30 * 1000 當eureka服務器啓動時獲取其他服務器的註冊信息失敗時,會再次嘗試獲取,期間需要等待的時間,默認爲30 * 1000毫秒
remote-region-app-whitelist 必須通過遠程區域中檢索的應用程序的列表
remote-region-connect-timeout-ms 1000 連接到對等遠程地eureka節點的超時時間,默認爲1000毫秒
remote-region-connection-idle-timeout-seconds 30 http連接被清理之後遠程地區服務器的空閒時間,默認爲30秒
remote-region-fetch-thread-pool-size 20 用於執行遠程區域註冊表請求的線程池的大小,默認爲20
remote-region-read-timeout-ms 1000 獲取從遠程地區eureka節點讀取信息的超時時間,默認爲1000毫秒
remote-region-registry-fetch-interval 30 從遠程區域取出該註冊表的信息的時間間隔,默認爲30秒
remote-region-total-connections 1000 獲取遠程地區對等節點上http連接的總數,默認爲1000
remote-region-total-connections-per-host 500 獲取遠程地區特定的對等節點上http連接的總數,默認爲500
remote-region-trust-store 用來合格請求遠程區域註冊表的信任存儲文件,默認爲空
remote-region-trust-store-password 獲取偏遠地區信任存儲文件的密碼,默認爲“changeit”
remote-region-urls 遠程地區的URL列表
remote-region-urls-with-name 針對遠程地區發現的網址域名的map
renewal-percent-threshold 0.85 閾值因子,默認是0.85,如果閾值比最小值大,則自我保護模式開啓
renewal-threshold-update-interval-ms 15 * 60 * 1000 閾值更新的時間間隔,單位爲毫秒
response-cache-auto-expiration-in-seconds 180 當註冊表信息被改變時,則其被保存在緩存中不失效的時間,默認爲180秒
response-cache-update-interval-ms 30 * 1000 客戶端的有效負載緩存應該更新的時間間隔,默認爲30 * 1000毫秒
retention-time-in-m-s-in-delta-queue 3 * 60 * 1000 客戶端保持增量信息緩存的時間,從而保證不會丟失這些信息,單位爲毫秒
route53-bind-rebind-retries 3 服務器嘗試綁定到候選Route53域的次數
route53-binding-retry-interval-ms 5 * 60 * 1000 服務器應該檢查是否和Route53域綁定的時間間隔,默認爲5 * 60 * 1000毫秒
route53-domain-t-t-l 301 用於建立route53域的ttl,默認爲301
sync-when-timestamp-differs true 當時間變化實例是否跟着同步,默認爲true
use-read-only-response-cache true 目前採用的是二級緩存策略,一個是讀寫高速緩存過期策略,另一個沒有過期只有只讀緩存,默認爲true,表示只讀緩存
wait-time-in-ms-when-sync-empty 1000 * 60 * 5 在Eureka服務器獲取不到集羣裏對等服務器上的實例時,需要等待的時間,單位爲毫秒,默認爲1000 * 60 * 5
xml-codec-name 如果沒有設置默認的編解碼器將使用xml編解碼器,獲取的是編碼器的類名稱

SpringCloudFegin

官方文檔:https://cloud.spring.io/spring-cloud-static/spring-cloud-openfeign/2.0.2.RELEASE/single/spring-cloud-openfeign.html

一、導入jar

Springboot 2.0.0 以下

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

Springboot 2.0.0 及以上

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
二、建立相關類

啓動類(加上註解):

/**
  * 如果爲了把eureka共有接口抽成單獨模塊,需註明掃描包,纔可以加載jar包中的@FeignClient
  * @EnableFeignClients(basePackages = { "com.lemon.soa.api" })
  */
@EnableFeignClients

修改類:

package com.lemon.soa.api;

// 其中eureka-provider是提供服務者的應用名,即eureka-provider的應用名
@FeignClient(name = "eureka-provider")
public interface VideoService {
   /**
    * 獲取視頻信息
    * @param videoId 視頻id
    * @return 視頻信息
    */
   @GetMapping(value = "/{videoId}")
   double getVideo(long videoId);
}

調用服務:

package com.lemon.consumer.controller;

import com.lemon.soa.api.dto.CategoryDTO;
import com.lemon.soa.api.provider.CategoryProvider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author sjp
 * @date 2019/1/24
 **/
@RestController
public class ConsumerController {
 
	/**
	 * feign 方式
	 */
	@Resource
	private CategoryProvider categoryProvider;

	@GetMapping(value = "/category")
	public List<CategoryDTO> getCategoryTree() {
		return categoryProvider.getCategoryTree();
	}

}

三、配置yml
server:
    port: 9003

spring:
    application:
        name: eureka-consumer
eureka:
    instance:
        # 使用IP註冊
        prefer-ip-address: true
    #註冊地址
    client:
        service-url:
            defaultZone: http://localhost:9001/eureka/
四、訪問

http://localhost:9001/

在這裏插入圖片描述
坑:

問題一:

有些公共的組件抽出來其他模塊的maven依賴,此時要在使用的項目中加載此jar包的spring component以及feign組件,僅僅依靠@ComponentScan是不夠的,還需要在@EnableFeignClients(basePackages = {“com.xixicat”})中標註basekPackages。

問題二:

使用@FeignClient註解,要求name不重複,否則Bean會被覆蓋,或者無法啓動。這是Feign的一個缺點吧。

推薦修復方案:

spring:

    # 允許重複名稱的bean定義,爲了解決Fegin重複命名無法啓動的問題
    main:
        allow-bean-definition-overriding: true

其他修復方案(手動初始化Feign代理的類):

package com.lemon.consumer.controller;

import com.lemon.soa.api.dto.CategoryDTO;
import com.lemon.soa.api.dto.VideoDTO;
import com.lemon.soa.api.provider.CategoryProvider;
import com.lemon.soa.api.provider.VideoProvider;
import feign.Client;
import feign.Contract;
import feign.Feign;
import feign.Logger;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.slf4j.Slf4jLogger;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.context.annotation.Import;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * FeginMutiNameController Fegin的一個缺陷,feginName不可以重複定義(除set allow-bean-definition-overriding: true的第二種方案)
 * @author sjp
 * @date 2019/12/15
 */
@RestController
@Import(FeignClientsConfiguration.class)
public class FeginMutiNameController {

	private VideoProvider		videoProvider;
	private CategoryProvider	categoryProvider;

	public FeginMutiNameController(Decoder decoder, Encoder encoder, Client client, Contract contract) {
		this.videoProvider = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
				// 默認是Logger.NoOpLogger
				.logger(new Slf4jLogger(VideoProvider.class))
				// 默認是Logger.Level.NONE
				.logLevel(Logger.Level.FULL).target(VideoProvider.class, "http://provider");

		this.categoryProvider = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
				// 默認是Logger.NoOpLogger
				.logger(new Slf4jLogger(CategoryProvider.class))
				// 默認是Logger.Level.NONE
				.logLevel(Logger.Level.FULL).target(CategoryProvider.class, "http://provider");
	}

	@GetMapping(value = "/test1")
	public List<CategoryDTO> getCategoryTree() {
		return categoryProvider.getCategoryTree();
	}

	@GetMapping(value = "/test2/{id}")
	public VideoDTO index(@PathVariable(value = "id") Long id) {
		return videoProvider.getVideo(id);
	}

}

SpringCloud使用Config作爲配置中心

一、介紹

​ 服務端:配置中心

​ 客戶端:接受配置的應用

二、配置

1、Server端配置

A、pom
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-parent</artifactId>
    <version>1.5.13.RELEASE</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
  </dependencies>

  <!-- 添加spring-boot的maven插件 -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
B、yml
server:
    port: 9000
spring:
    application:
        name: lemon-config-server
    cloud:
        config:
            server:
                git:
                	# SpringCloud Config 的配置是放在git上的
                    uri: https://github.com/ATSJP/lemon-config
                    # 指定搜索根路徑下的所有目錄,若有多個路徑使用逗號隔開
                    search-paths: /**  
C、Application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

/**
 * @author sjp
 */
@EnableConfigServer
@SpringBootApplication
public class LemonConfigApplication {

	public static void main(String[] args) {
		SpringApplication.run(LemonConfigApplication.class, args);
	}

}

全部配置好後,啓動應用,訪問 http://localhost:9000/admin/dev (http://localhost:9000/admin-dev.json,http://localhost:9000/admin-dev.properties)

在這裏插入圖片描述

注:配置文件的訪問規則如下:

/{name}-{profiles}.yml
/{label}/{name}-{profiles}.yml

name : 文件名,一般以服務名來命名
profiles : 一般作爲環境標識
lable : 分支(branch),指定訪問某分支下的配置文件

例如:http://localhost:9000/dv_lemon_2019_07/provider-dev.yml

有一點值得注意的是,如果有兩個前綴名相同文件,例如一個order.yml,一個order-dev.yml。那麼在訪問相同前綴的文件時,config-server會對這兩個文件進行一個合併。例如order.yml有一段配置是order-dev.yml沒有的,理應訪問order-dev.yml的時候是沒有那段配置的,但訪問的結果卻是它倆合併之後的內容,即order-dev.yml會擁有order.yml裏所配置的內容。

2、Client端配置

A、pom
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-parent</artifactId>
    <version>1.5.13.RELEASE</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 實現Config的客戶端配置 -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <!-- 實現通過端點refresh手動刷新 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
  </dependencies>
  
  <!-- 添加spring-boot的maven插件 -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
B、yml
  1. bootstrap.yml
# 對應着config server所獲取配置文件的{application}和URL
spring:
    application:
        name: admin
    cloud:
        config:
            uri: http://localhost:9000/
            # 對應着文件後面的後綴{profile}
            profile: dev
            # 分支
            label: master
  1. application.yml
version-config: ${version}
C、Application
@SpringBootApplication
public class LemonAdminApplication {

	public static void main(String[] args) {
		SpringApplication.run(LemonAdminApplication.class, args);
	}

}
D、Controller
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Controller
@RestController
public class LoginController {

    @Value("${version-config}")
    private String version;

    @GetMapping("/test")
    public String getVersion() {
        return this.version;
    }
    
}

三、踩坑

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章