微服務條目 | 落地技術 |
---|---|
服務開發 | SpringBoot,Spring,SpringMVC |
服務配置與管理 | Netflix公司的Archaius、阿里的Diamond等 |
服務註冊與發現 | Eureka、Consul、Zookeeper等 |
服務調用 | Rest、RPC、gRPC |
服務熔斷器 | Hystrix、Envoy等 |
負載均衡 | Ribbon、Nginx等 |
服務接口調用(客戶端調用服務的簡化工具) | Feign等 |
消息隊列 | Kafka、RabbitMQ、ActiveMQ等 |
服務配置中心管理 | SpringCloudConfig、Chef等 |
服務路由(API網關) | Zuul等 |
服務監控 | Zabbix、Nagios、Metrics、Specatator等 |
全鏈路追蹤 | Zipkin、Brave、Dapper等 |
服務部署 | Docker、OpenStack、Kubernetes等 |
數據流操做開發包 | SpringCloud Stream(封裝與Redis,Rabbit,Kafka等發送接收消息) |
事件消息總線 | SpringCloud Bus |
功能點/服務框架 | Netflix/SpringCloud | Motan | gRPC | Thrift | Dubbo/DubboX |
---|---|---|---|---|---|
功能定位 | 完整的微服務架構 | RPC框架,但整合了ZK或Consul,實現集羣環境的基本服務註冊/發現 | RPC框架 | RPC框架 | 服務框架 |
支持Rest | 是,Ribbon支持多種可插拔的序列化選擇 | 否 | 否 | 否 | 否 |
支持RPC | 否 | 是 | 是 | 是 | 是 |
支持多語言 | 是(Rest形式) | 否 | 是 | 是 | 否 |
服務註冊/發現 | 是(Eureka) Eureka服務註冊表,Karyon服務端框架支持服務自注冊和健康檢查 | 是(zookeeper/consul) | 否 | 否 | 是 |
負載均衡 | 是(服務端zuul+客戶端Ribbon) zuul-服務,動態路由 雲端負載均衡 Eureka(針對中間層服務器) | 是(客戶端) | 否 | 否 | 是(客戶端) |
配置服務 | Netflix Archaius SpringCloud Config Server集中配置 | 是(zookeeper提供) | 否 | 否 | 否 |
服務調用鏈監控 | 是(zuul) Zuul提供邊緣服務,API網關 | 否 | 否 | 否 | 否 |
高可用/容錯 | 是(服務端Hystrix+客戶端Ribbon) | 是(客戶端) | 否 | 否 | 是(客戶端) |
典型應用案例 | Netflix | Sina | |||
社區活躍度 | 高 | 通常 | 高 | 通常 | 2017年7月才重啓 |
學習難度 | 中等 | 通常 | 高 | 通常 | 低 |
文檔豐富度 | 高 | 通常 | 通常 | 通常 | 高 |
其餘 | Spring Cloud Bus爲咱們應用程序帶來了更多管理端點 | 支持降級 | Netflix內部在開發集成gRPC | IDL定義 | 實踐公司比較多 |
SpringBoot:專一於快速方便的開發單個個體微服務(關注微觀)java
SpringCloud:關注全局的微服務協調治理框架,將SpringBoot開發的一個個單體微服務組合並管理起來(關注宏觀)mysql
Dubbo | Spring | |
---|---|---|
服務註冊中心 | Zookeeper | Spring Cloud Netfilx Eureka |
服務調用方式 | RPC | REST API |
服務監控 | Dubbo-monitor | Spring Boot Admin |
斷路器 | 不完善 | Spring Cloud Netflix Hystrix |
服務網關 | 無 | Spring Cloud Netflix Zuul |
分佈式配置 | 無 | Spring Cloud Config |
服務跟蹤 | 無 | Spring Cloud Sleuth |
消息總線 | 無 | Spring Cloud Bus |
數據流 | 無 | Spring Cloud Stream |
批量任務 | 無 | Spring Cloud Task |
最大區別:ios
####總結git
概述:SpringCloud工程由一個父工程和若干個Module組成github
==應該遵循的條件:約定 > 配置 > 編碼==web
RestTemplate是Spring提供的用於訪問Rest服務的客戶端模板工具集,提供了多種遠程訪問Http的方法算法
在一些不涉及實現方法的模塊中(消費者),只須要調用其餘服務暴露出的接口便可知足的需求,使用RestTemplate類中的方法能夠發出須要的HTTP請求並獲得返回結果。(相似Ajax)spring
RestTemplate restTemplate = new RestTemplate();
//url:請求地址
//requestMap:請求參數
//type.class:HTTP響應轉換成的對象類型
restTemplate.getForObject(url,type.class);
restTemplate.postForObject(url,requestMap,type.class);
<dependencies>
<dependency>
<groupId>com.lzl</groupId>
<artifactId>microservice-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml
type-aliases-package: com.XXX.entity
mapper-locations:
- classpath:mybatis/mapper/**/*.xml
spring:
application:
name: microservicecloud-dept #爲這個服務取名,很是重要!!!!!
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/cloudDB01
username: root
password: 123456
dbcp2:
min-idle: 5 #最小鏈接數
initial-size: 5 #初始化鏈接數
max-total: 10 #最大鏈接數
max-wait-millis: 200 #等待鏈接最長的超時時間
package com.XXX;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Provider8001_APP {
public static void main(String[] args) {
SpringApplication.run(Provider8001_APP.class,args);
}
}
==Eureka就像一個物業管理公司,其餘微服務就像小區的住戶,每一個住戶入住時都要向物業管理公司註冊,並定時向物業公司交管理費==sql
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
server:
port: 7001
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false #false表示不向註冊中心註冊本身
fetch-registry: false #false表示本身就是註冊中心,職責是維護實例,不參加檢索
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #設置eureka server的交互地址,即對外暴露的地址
package com.XXX;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class Eureka7001_APP {
public static void main(String[] args) {
SpringApplication.run(Eureka7001_APP.class,args);
}
}
啓動主程序,訪問該服務地址便可shell
在要註冊的微服務的pom.xml文件中增長依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
@SpringBootApplication
@EnableEurekaClient
public class Provider8001_APP {
public static void main(String[] args) {
SpringApplication.run(Provider8001_APP.class,args);
}
}
eureka:
instance:
instance-id: dept8001 #修改別名
prefer-ip-address: true #顯示IP地址
在查看Eureka時點擊進入某個微服務的info時,能給查看者一些必要的信息,能夠幫助查看者快速的瞭解該微服務,開發中十分有意義。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<build>
<finalName>microservicecloud</finalName>
<resources>
<resource>
<!--容許掃描該路徑下的資源文件-->
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<!--指定動態獲取以$標誌開頭結尾的信息-->
<delimit>$</delimit>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
info:
author: XXX
build-version: $project.version$
Eureka的自我保護機制主要是爲了網絡異常時保持高可用設計的,當在Eureka中註冊的微服務超過設定是時間內(默認90秒)沒有向Eureka服務端發送心跳,該微服務會進入自我保護模式。在自我保護模式中,Eureka會保護服務註冊表中的信息,不會註銷任何服務實例,直至收到的心跳數恢復至閾值以上,該微服務退出自我保護模式。
好死不如賴活:Eureka的設計哲學是寧肯保留錯誤的服務信息,也不盲目註銷可能健康的服務。因此異常的服務不會被註銷,而是進入了自我保護模式。
在Eureka Server模塊下的yml文件中添加配置信息便可,true表示打開自我保護模式;false表示關閉自我保護模式(不推薦)
server:
enable-self-preservation: false
系統中的微服務能夠經過Eureka的服務發現去得到在Eureka中註冊的服務的信息,這是一個對外暴露的接口。
@Autowired
private DiscoveryClient discoveryClient;
@ResponseBody
@GetMapping("/provider/discovery")
public Object discovery(){
List<String> list = discoveryClient.getServices();
System.out.println(list);
List<ServiceInstance> insList = discoveryClient.getInstances("MICROSERVICECLOUD-DEPT");
for (ServiceInstance si:insList) {
System.out.println(si.getHost() +"," + si.getServiceId() +"," +si.getPort() +"," +si.getUri() +"," +si.getMetadata());
}
return this.discoveryClient;
}
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class Provider8001_APP {
public static void main(String[] args) {
SpringApplication.run(Provider8001_APP.class,args);
}
}
在controller方法中使用restTemplate對象調用provider中暴露的URL 並得到返回對象便可
@GetMapping("/discovery")
public Object discovery() {
return restTemplate.getForObject(URL_PREFIX+"/provider/discovery",Object.class);
}
集羣就是在不一樣的機器上配置相同的服務來構建要一個大的運算總體
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #hostname爲hosts文件中映射的地址
client:
register-with-eureka: false #false表示不向註冊中心註冊本身
fetch-registry: false #false表示本身就是註冊中心,職責是維護實例,不參加檢索
service-url:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #設置eureka server的交互地址
defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #其餘兩個服務端的地址
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
http://eureka7001.com:7001
http://eureka7002.com:7002
http://eureka7003.com:7003
Eureka遵照AP,Zookeeper遵照CP(C:強一致性,A:高可用,P:分區容錯性,三者只能選其二,高併發下P必選)
Zookeeper | Eureka |
---|---|
當網絡出現故障時,剩餘zk集羣會發起投票選舉新的leader,可是此過程會持續30~120s,此過程對於高併發來講十分漫長,會致使整個註冊服務的癱瘓,這是不可容忍的 | 在15分鐘內85%的節點都沒有心跳,則註冊中心 會認爲客戶端與之出現了網絡故障,則會進入自動保護模式。1.Eureka不會移除沒有收到心跳的服務;2.新的服務仍能在服務端註冊,可是暫時不會被同步到其餘節點上直到網絡穩定 |
Eureka能夠很好的應對網絡故障致使部分節點失去鏈接的狀況,而不會像zookeeper那樣致使整個註冊服務系統的癱瘓。
Spring Cloud Ribbon是基於Netflix Ribbon實現的一套==客戶端==負載均衡工具。Ribbon會自動幫助你基於某種規則(簡單輪詢、隨機鏈接等),也能夠實現自定義的負載均衡算法。
英文名稱:Load Balance,微服務或分佈式集羣中經常使用的一種應用
簡單來講負載均衡就是將用戶的請求ping平攤的分配到多個任務上,從而是系統達到HA(高可用)
兩種負載均衡:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
register-with-eureka: false #做爲消費者不提供服務,不該該註冊本身
@SpringBootApplication
@EnableEurekaClient
public class Consumer80_APP {
public static void main(String[] args) {
SpringApplication.run(Consumer80_APP.class,args);
}
}
private static final String URL_PREFIX = "http://MICROSERVICECLOUD-DEPT/";
架構示意圖:
目標:構建provider集羣后consumer經過負載均衡輪詢調用在Eureka中註冊的服務
spring:
application:
name: microservicecloud-dept #同一集羣下必須使用同一服務名!!!!!
Ribbon其實就是一個軟負載均衡的客戶端組件,能夠和其餘須要請求的客戶端結合使用。
IRule:根據特定算法從服務列表中選取一個須要訪問的服務
==IRule是一個接口,七大方法是其自帶的落地實現類==
只需在==配置類==中配置一個返回具體方法的bean便可
@Bean
public IRule MyRule(){
return new RandomRule();
}
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration = MyRule.class)
public class Consumer80_APP {
public static void main(String[] args) {
SpringApplication.run(Consumer80_APP.class,args);
}
}
####經過修改源代碼得到自定義算法
目標:每一個服務調用5次後再進行輪詢(調用次數不是很對,懶得改了)
package com.Rules;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.RoundRobinRule;
import com.netflix.loadbalancer.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class MyRule extends AbstractLoadBalancerRule {
private AtomicInteger nextServerCyclicCounter;
private static final boolean AVAILABLE_ONLY_SERVERS = true;
private static final boolean ALL_SERVERS = false;
private int total = 0;
private int currentIndex = 0;
private static Logger log = LoggerFactory.getLogger(RoundRobinRule.class);
public MyRule() {
nextServerCyclicCounter = new AtomicInteger(0);
}
public MyRule(ILoadBalancer lb) {
this();
setLoadBalancer(lb);
}
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
log.warn("no load balancer");
return null;
}
Server server = null;
int count = 0;
while (server == null && count++ < 10) {
List<Server> reachableServers = lb.getReachableServers();
List<Server> allServers = lb.getAllServers();
int upCount = reachableServers.size();
int serverCount = allServers.size();
if ((upCount == 0) || (serverCount == 0)) {
log.warn("No up servers available from load balancer: " + lb);
return null;
}
if (total > 5) {
total = 0;
int nextServerIndex = incrementAndGetModulo(serverCount);
currentIndex = nextServerIndex;
server = allServers.get(nextServerIndex);
}else {
if (currentIndex>=serverCount) {
currentIndex = 0;
}
server = allServers.get(currentIndex);
total++;
}
if (server == null) {
/* Transient. */
Thread.yield();
continue;
}
if (server.isAlive() && (server.isReadyToServe())) {
return (server);
}
// Next.
server = null;
}
if (count >= 10) {
log.warn("No available alive servers after 10 tries from load balancer: "
+ lb);
}
return server;
}
/**
* Inspired by the implementation of {@link AtomicInteger#incrementAndGet()}.
*
* @param modulo The modulo to bound the value of the counter.
* @return The next value.
*/
private int incrementAndGetModulo(int modulo) {
for (;;) {
int current = nextServerCyclicCounter.get();
int next = (current + 1) % modulo;
if (nextServerCyclicCounter.compareAndSet(current, next))
return next;
}
}
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
Feign是一個聲明式WebService客戶端,使用方法時定義一個接口並在上面添加註解便可。Feign支持可拔插式的編碼器和解碼器。Spring Cloud對Feign進行了封裝,使其支持SpringMVC和HttpMessageConverters。Feign能夠與Eureka和Ribbon組合使用以支持負載均衡。
<dependencies>
<dependency>
<groupId>com.XXX</groupId>
<artifactId>microservice-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--熱部署-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
@FeignClient(value = "MICROSERVICECLOUD-DEPT")
public interface DeptClientService {
@PostMapping("/dept")
public boolean addDept(Dept dept);
@GetMapping("/dept")
public List<Dept> findAll();
@GetMapping("/dept/{id}")
public Dept findById(@PathVariable("id")Integer id);
}
@RestController
@RequestMapping("/consumer")
public class ConsumerDeptController {
@Autowired
private DeptClientService service;
@PostMapping("/dept")
public boolean addDept(Dept dept){
return service.addDept(dept);
}
@GetMapping("/dept")
public List<Dept> findAll(){
return service.findAll();
}
@GetMapping("/dept/{id}")
public Dept findById(@PathVariable("id")Integer id){
return service.findById(id);
}
}
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.XXX"})
@ComponentScan("com.XXX")
public class Consumer80Feign_APP {
public static void main(String[] args) {
SpringApplication.run(Consumer80Feign_APP.class,args);
}
}
多個微服務互相調用的時候,若是A調用B、C,而B、C又繼續調用其餘微服務,這就是扇出(像一把扇子同樣慢慢打開。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
@ResponseBody
@GetMapping("/dept/{id}")
@HystrixCommand(fallbackMethod = "nullDeptFallBack")
public Dept findById(@PathVariable("id")Integer id) {
Dept dept = deptService.findById(id);
if (null == dept){
throw new RuntimeException("返回值爲空!");
}
return dept;
}
public Dept nullDeptFallBack(@PathVariable("id")Integer id) {
System.out.println(111);
return new Dept().setId(id).setDeptName("nullName").setDbSource("nullDB");
}
若是按照上面的熔斷案例來作的話,Controller下的每一個方法,都要給其編寫一個FallBack方法,當方法慢慢變多,就會形成代碼膨脹,一個是增長編寫的工做量,另一個也會增大維護的難度,代碼的耦合度也會高,是十分不合理的,因此要將其解耦。
由於服務端的是經過實現接口訪問服務端的,若是在父接口上實現了FallBack方法,經過這樣一種方式去維護起來就能實現解耦,也順便完成了降級的機制。
import com.XXX.entity.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class DeptClientServiceFallBackFactory implements FallbackFactory<DeptClientService> {
public DeptClientService create(Throwable throwable) {
return new DeptClientService() {
public boolean addDept(Dept dept) {
return false;
}
public List<Dept> findAll() {
return null;
}
public Dept findById(Integer id) {
return new Dept().setId(id).setDeptName("服務器跪了,").setDbSource("遲點來吧");
}
};
}
}
@FeignClient(value = "MICROSERVICECLOUD-DEPT",fallbackFactory = DeptClientServiceFallBackFactory.class)
public interface DeptClientService {
@PostMapping("/dept")
public boolean addDept(Dept dept);
@GetMapping("/dept")
public List<Dept> findAll();
@GetMapping("/dept/{id}")
public Dept findById(@PathVariable("id")Integer id);
}
feign:
hystrix:
enabled: true
介紹:SpringCloud對Hystrix Dashboard進行了整合,能夠對經過Hystrix發起的請求進行準實時統計,並以報表和圖形的形式展現給用戶(包括每秒執行多少次請求成功和失敗等)。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
@SpringBootApplication
@EnableHystrixDashboard
public class DashBoard9001_APP {
public static void main(String[] args) {
SpringApplication.run(DashBoard9001_APP.class,args);
}
}
代理:Zuul提供外部的請求轉發到具體的微服務實例中的服務
路由:Zuul能夠對外部訪問實現統一的入口
過濾:Zuul能夠對外部訪問進行干預,如請求校驗、服務聚合等
Zuul須要配合Eureka使用,須要在Eureka中註冊並得到其餘微服務的信息
理解:Zuul就像大樓的保安,能夠請他找人(代理),找的人在外面叫什麼名字(路由),準不許你進樓(過濾)。由於保安屬於物業公司,因此保安要在物業公司註冊,所得到的信息也來源於物業公司(與Eureka的關係)。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
server:
port: 9527
spring:
application:
name: microservicecloud-zuul #爲這個服務取名,很是重要!!!!!
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance:
instance-id: zuul.com
prefer-ip-address: true
127.0.0.0 zuul.com
@SpringBootApplication
@EnableZuulProxy
public class Zuul9527_APP {
public static void main(String[] args) {
SpringApplication.run(Zuul9527_APP.class,args);
}
}
啓動測試,訪問規則:步驟3中指定映射+端口號+微服務名稱+訪問路徑。
當不向暴露真實的服務名時,能夠對服務名進行映射,只需在application.yml中配置便可,==具體做用看註釋==
zuul:
routes:
#dept0是能夠自定義的只是做爲區分,沒什麼具體意義
dept0.serviceId: microservicecloud-dept
#路徑也是自定義的,支持通配符
dept0.path: /dept10/**
#須要隱藏的服務名,可使用通配符,配置以後經過這個微服務名訪問就失效了
ignored-services: microservicecloud-*
#設置統一公共前綴,設置後訪問路徑:http://zuul.com:9527/nihao/dept10/dept/3
prefix: /nihao
==注:由於Zuul是針對外部訪問管理的,因此配置了隱藏的服務,在系統中其餘模塊進行服務名訪問時依然能夠正常運行的,這點能夠經過打開consumer模塊進行驗證!==
分佈式系統面臨的配置問題:微服務意味着將單體應用拆分紅一個個自服務,這些服務都是要相應的配置信息才能運行,隨着系統內微服務數量愈來愈多,配置信息也不斷地增多,因此一套集中式的、動態的配置管理設施是必不可少的。
![SpringCloud Config架構圖](E:\筆記\images\SpringCloud Config架構圖.png)
目標:將配置文件部署在github,Config服務端從github獲取配置
<!-- springCloud Config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!-- 避免Config的Git插件報錯:org/eclipse/jgit/api/TransportConfigCallback -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.10.0.201712302008-r</version>
</dependency>
spring:
profiles:
active:
- dev
---
spring:
profiles: dev
application:
name: microservicecloud-config-XXX-dev
---
spring:
profiles: test
application:
name: microservicecloud-config-XXX-test
server:
port: 3344
spring:
application:
#爲這個服務取名,很是重要!!!!!
name: microservicecloud-config
cloud:
config:
server:
git:
# uri填github上倉庫地址
uri: https://github.com/XXXX/SpringCloud_Configuration.git
@SpringBootApplication
@EnableConfigServer
public class ConfigServer3344_APP {
public static void main(String[] args) {
SpringApplication.run(ConfigServer3344_APP.class,args);
}
}
/{application}/{profile}[/{lable}]
/{application}-{profile}.yml
/{lable}/{application}-{profile}.yml
/{application}-{profile}.properties
/{lable}/{application}-{profile}.properties
可用例子(返回格式可能不大相同,但返回值相同):
不可用例子:
介紹:客戶端主要是在==加載時==經過config server服務端得到github配置倉庫的地址,進而經過目標配置文件的文件名獲取相應的配置,最後將取得的配置對自身資源進行賦值並提供訪問
1.建立遠程配置yml文件並上傳到github上。以下測試案例由於須要進行測試,因此配置了兩個profiles方便切換並觀察
spring:
profiles:
active:
- dev
---
server:
port: 8201
spring:
profiles: dev
application:
name: microservicecloud-config-client-dev
eureka:
client:
service-url:
defaultZone: http://eureka-dev.com:7001/eureka/
---
server:
port: 8202
spring:
profiles: test
application:
name: microservicecloud-config-client-test
eureka:
client:
service-url:
defaultZone: http://eureka-dev.com:7001/eureka/
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
spring:
cloud:
config:
name: application_config #須要從github上讀取的資源名稱,注意沒有yml後綴名
profile: test #本次訪問的配置項
label: master
uri: http://config3344.com:3344 #本微服務啓動後先去找3344號服務,經過SpringCloudConfig獲取GitHub的服務地址
spring:
application:
name: microservicecloud_config
@org.springframework.web.bind.annotation.RestController
public class RestController {
@Value("${server.port}")
private String port;
@Value("${eureka.client.service-url.defaultZone}")
private String eurekaZone;
@Value("${spring.application.name}")
private String name;
@GetMapping("/config")
@Override
public String toString() {
return "RestController{" +
"port='" + port + '\'' +
", eurekaZone='" + eurekaZone + '\'' +
", name='" + name + '\'' +
'}';
}
}
介紹:其實前面client的配置案例都是幫助理解這個組件爲主,並無很大的實際意義。。。。。。這節的案例中是配置一個Provider,一個eureka,他們的配置統一在github上獲取,實現統一配置分佈式管理和多環境變動,這個才比較有實戰意義。
Eureka配置文件示例:
spring:
profiles:
active:
- dev
---
spring:
profiles: dev
application:
name: microservicecloud-eureka-client-dev
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #hostname爲hosts文件中映射的地址
client:
register-with-eureka: false #false表示不向註冊中心註冊本身
fetch-registry: false #false表示本身就是註冊中心,職責是維護實例,不參加檢索
service-url:
defaultZone: http://eureka7001.com:7001/eureka/ #設置eureka server的交互地址
---
spring:
profiles: test
application:
name: microservicecloud-eureka-client-dev
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #hostname爲hosts文件中映射的地址
client:
register-with-eureka: false #false表示不向註冊中心註冊本身
fetch-registry: false #false表示本身就是註冊中心,職責是維護實例,不參加檢索
service-url:
defaultZone: http://eureka7001.com:7001/eureka/ #設置eureka server的交互地址
Provider配置文件示例:
spring:
profiles:
active:
- dev
---
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml
type-aliases-package: com.XXX.entity
mapper-locations:
- classpath:mybatis/mapper/**/*.xml
spring:
profiles: dev
application:
name: microservicecloud-dept #爲這個服務取名,很是重要!!!!!
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://192.168.88.246:3306/cloudDB01
username: root
password: 123456
dbcp2:
min-idle: 5 #最小鏈接數
initial-size: 5 #初始化鏈接數
max-total: 10 #最大鏈接數
max-wait-millis: 200 #等待鏈接最長的超時時間
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
instance:
instance-id: dept8001
prefer-ip-address: true
---
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml
type-aliases-package: com.XXX.entity
mapper-locations:
- classpath:mybatis/mapper/**/*.xml
spring:
profiles: test
application:
name: microservicecloud-dept #爲這個服務取名,很是重要!!!!!
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://192.168.88.246:3306/cloudDB02
username: root
password: 123456
dbcp2:
min-idle: 5 #最小鏈接數
initial-size: 5 #初始化鏈接數
max-total: 10 #最大鏈接數
max-wait-millis: 200 #等待鏈接最長的超時時間
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
instance:
instance-id: dept8001
prefer-ip-address: true
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
spring:
cloud:
config:
name: application_config #須要從github上讀取的資源名稱,注意沒有yml後綴名
profile: test #本次訪問的配置項
label: master
uri: http://config3344.com:3344 #本微服務啓動後先去找3344號服務,經過SpringCloudConfig獲取GitHub的服務地址
spring:
application:
name: microservicecloud_config