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
- bootstrap.yml
# 對應着config server所獲取配置文件的{application}和URL
spring:
application:
name: admin
cloud:
config:
uri: http://localhost:9000/
# 對應着文件後面的後綴{profile}
profile: dev
# 分支
label: master
- 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;
}
}