一.使用注冊中心背景?
1.1服務遠程調用問題
服務之間遠程調?時, 我們的URL是寫死的?
String url = "http://127.0.0.1:9090/product/"+ orderInfo.getProductId();
缺點:
解決方法:
這樣就類似解決高耦合的思想,引入第三方來保存保存和交互雙方信息
- 號碼注冊: 服務方把電話上報給114
- 號碼查詢: 使用方通過114可以查到對應的號碼
?
- 服務啟動/變更時, 向注冊中心報道. 注冊中心記錄應用和IP的關系.
- 調??調?時, 先去注冊中心獲取服務?的IP, 再去服務?進?調?
?1.2什么是注冊中心
?注冊中?主要有三種??:
- 服務提供者(Server):?次業務中, 被其它微服務調用的服務. 也就是提供接?給其它微服務.
- 服務消費者(Client):?次業務中, 調用其它微服務的服務. 也就是調?其它微服務提供的接?.
- 服務注冊中?(Registry): ?于保存Server 的注冊信息, 當Server 節點發?變更時, Registry 會同步變更. 服務與注冊中?使??定機制通信, 如果注冊中?與某服務?時間?法通信, 就會注銷該實例
1.3CAP理論
CAP 理論是分布式系統設計中最基礎, 也是最為關鍵的理論. ?
- ?致性(Consistency) CAP理論中的?致性, 指的是強?致性. 所有節點在同?時間具有相同的數據
- 可?性(Availability) 保證每個請求都有響應(響應結果可能不對)
- 分區容錯性(Partition Tolerance) 當出現?絡分區后,系統仍然能夠對外提供服務
?個部門全國各地都有崗位, 這時候, 總部下發了?個通知, 由于通知需要開會周知全員, 當有客戶咨詢時:所有成員對客戶的回應結果都是?致的(?致性)客戶咨詢時, ?定有回應(可用性)當其中?個成員休假時, 這個部門的其他成員也可以對客戶提供咨詢服務(分區容錯性)
- 如果要保證一致性,總部有了新通知,就必須等所有地區的成員都收到通知后,才能統一回應客戶。但這樣在網絡故障期間,那些沒收到通知的地區成員就無法回應客戶,也就犧牲了可用性。
? - 如果要保證可用性,不管網絡有沒有問題,只要客戶來咨詢,成員們就得馬上回應。但這樣一來,在網絡分區的情況下,那些沒收到新通知的成員可能就會給出和收到通知的成員不一樣的回應,也就犧牲了一致性。
1.4常見的注冊中心
- Zookeeper:
Zookeeper的官?并沒有說它是?個注冊中?, 但是國內Java體系, ?部分的集群環境都是依賴 Zookeeper來完成注冊中?的功能. - Eureka:
Eureka是Netflix開發的基于REST的服務發現框架, 主要?于服務注冊, 管理,負載均衡和服務故障轉移. 官?聲明在Eureka2.0版本停?維護, 不建議使?. 但是Eureka是SpringCloud服務注冊/發現的默認實現, 所以?前還是有很多公司在使?. - Nacos:
Nacos是Spring Cloud Alibaba架構中重要的組件, 除了服務注冊, 服務發現功能之外, Nacos還?持配置管理, 流量管理, DNS, 動態DNS等多種特性
?CAP理論對比?
?
二.Eureka介紹
- Eureka Server: 作為注冊中心Server端, 向微服務應?程序提供服務注冊, 發現, 健康檢查等能力.
- Eureka Client: 服務提供者, 服務啟動時, 會向Eureka Server 注冊??的信息(IP,端?,服務信息 等),Eureka Server 會存儲這些信息
- 搭建Eureka Server
- 將order-service, product-service 都注冊到Eureka
- order-service遠程調?時, 從Eureka中獲取product-service的服務列表, 然后進?交互
2.1搭建Eureka Server
?Eureka-server 是?個獨立的微服務,我也通過子項目形式編寫
1.搭建注冊中心
2.pom文件添加Eureka依賴
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
3.?創建配置文件,增加Eureka相關的配置
server:port: 10010
spring:application:name: eureka-server
eureka:instance:hostname: localhostclient:fetch-registry: false # 表示是否從Eureka Server獲取注冊信息,默認為true.因為這是一個單點的Eureka Server,不需要同步其他的Eureka Server節點的數據,這里設置為falseregister-with-eureka: false # 表示是否將自己注冊到Eureka Server,默認為true.由于當前應用就是Eureka Server,故而設置為false.service-url:# 設置Eureka Server的地址,查詢服務和注冊服務都需要依賴這個地址defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
4.啟動類,開啟Eureka的功能
?
package eureka;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@EnableEurekaServer
@SpringBootApplication
public class EurekaServiceApplication {public static void main(String[] args) {SpringApplication.run(EurekaServiceApplication.class,args);}
}
?5.啟動項目成功嘿嘿
2.2服務注冊?
服務注冊:針對提供給order訂單服務的product產品服務?
接下來我們把product-service 注冊到eureka-server中
1. product的pom文件加入Eureka的依賴?
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
?
2. application.yml修改配置信息
1.添加該服務的信息
2.添加相關eureka配置信息?
3. 啟動,測試
2.3服務發現
服務發現:針對消費produc產品服務的order訂單服務
1. 加入Eureka依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
2.application.yml修改配置信息
1.添加該服務的信息
2.添加相關eureka配置信息?
servic:port: 8080spring:application:name: order-servicedatasource:url: jdbc:mysql://127.0.0.1:3306/cloud_order?characterEncoding=utf8&useSSL=falseusername: rootpassword: weigang527driver-class-name: com.mysql.cj.jdbc.Drivermvc:favicon:enable: falseprofiles: #多平臺配置active: dev
# 設置 Mybatis 的 xml 保存路徑
mybatis:mapper-locations: classpath:mapper/*Mapper.xmlconfiguration: # 配置打印 MyBatis 執行的 SQLlog-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true #自動駝峰轉換
eureka:client:service-url:defaultZone: http://127.0.0.1:10010/eureka/
3.service層修改遠程調用的代碼
package order.service;import lombok.extern.slf4j.Slf4j;
import order.mapper.OrderMapper;
import order.model.OrderInfo;
import order.model.ProductInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;import java.util.List;
@Slf4j
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;//注入這個接口@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;//注意這個有多個同名,使用.cloud.client后綴的public OrderInfo selectOrderById(Integer orderId){OrderInfo orderInfo = orderMapper.selectOrderById(orderId);//String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();//從Eureka中獲取服務列表(因為可能不止一個服務,所有使用列表,然后再選擇列表中的product服務)List<ServiceInstance> instances = discoveryClient.getInstances("product-service");String uri = instances.get(0).getUri().toString();String url = uri+"/product/" + orderInfo.getProductId();log.info("遠程調用url:{}",url);ProductInfo productInfo = restTemplate.getForObject(url,ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}
4. 啟動,測試?
5.查看遠程調用是否成功
?
2.4Eureka 和Zookeeper區別
- Eureka是Netflix開源的項目, 而Zookeeper是Apache開源的項?.
- Eureka 基于AP原則, 保證?可用, Zookeeper基于CP原則, 保證數據?致性.
- Eureka 每個節點都是均等的, Zookeeper的節點區分Leader 和Follower 或 Observer, 也正因為這個原因, 如果Zookeeper的Leader發?故障時, 需要重新選舉, 選舉過程集群會有短暫時間的不可?