1.初識微服務
1.1.什么是微服務
微服務,就是把服務拆分成為若干個服務,降低服務之間的耦合度,提供服務的獨立性和靈活性。做到高內聚,低耦合。
1.2.單體架構和微服務架構的區別:
-
單體架構:簡單方便,高度耦合,擴展性差,適合小型項目。例如:學生管理系統
-
分布式架構:松耦合,擴展性好,但架構復雜,難度大。適合大型互聯網項目,例如:京東、淘寶
-
微服務:一種良好的分布式架構方案
①優點:拆分粒度更小、服務更獨立、耦合度更低
②缺點:架構非常復雜,運維、監控、部署難度提高
-
SpringCloud是微服務架構的一站式解決方案,集成了各種優秀微服務功能組件
1.3.什么是SpringCloud
SpringCloud是一種微服務框架,集成了各種微服務功能組件,并基于SpringBoot實現了這些組件的自動裝配,從而提供了良好的開箱即用體驗。
1.4.微服務技術對比
2.Eureka注冊中心
如果沒有Eureka,就要把服務調用代碼寫死,下面是例子
//配置類注冊restTemplate的bean
@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
@Autowired
private RestTemplate restTemplate;
String url = "http://localhost:8081/user/"+order.getUserId();
User user = restTemplate.getForObject(url,User.class);
order.setUser(user);
Eureka架構中,微服務角色有兩類
- EurekaServer:服務端,注冊中心
- 記錄服務信息
- 心跳監控
- EurekaClient:客戶端
- Provider:服務提供者
- 注冊自己的信息到EurekaServer
- 每隔30秒向EurekaServer發送心跳
- consumer:服務消費者
- 根據服務名稱從EurekaServer拉去服務列表
- 基于服務列表做負載均衡,選中一個微服務后發起遠程調用
- Provider:服務提供者
2.1.Eureka作用
- 消費者如何獲取服務提供者具體信息?
- 提供者啟動時向eureka注冊自己的信息
- eureka保存這些信息
- 消費者根據服務名稱向eureka獲取提供者信息
- 如果有多個服務提供者,消費者利用負載均衡算法,從服務器列表挑選一個
- 消費者如何感知服務提供者健康狀態?
- 提供者每30s想EurekaServer發送心跳請求,報告健康狀態
- eureka會更新記錄服務器列表信息,不健康的會被刪除
- 消費者就可以拉取到最新信息
2.2.搭建Eureak服務
流程:搭建注冊中心 --> 服務注冊 --> 服務發現
2.2.1.搭建Eureka服務
1.引入依賴,服務器依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2.加注解@EnableEurekaServer
,表示啟用Eureka服務
package cn.itcast.eureka;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {public static void main(String[] args) {SpringApplication.run(EurekaApplication.class, args);}
}
3.編寫配置文件application.yml
,把eureka注冊為服務
server:port: 10086 # 服務端口
spring:application:name: eurekaserver # eureka的服務名稱
eureka:client:service-url: # eureka的地址信息defaultZone: http://127.0.0.1:10086/eureka
2.3.2.服務注冊
1.引入依賴,客戶端依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.注冊服務,配置eureka地址
spring:application:name: userservice
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka
2.3.3.服務發現(服務拉取)
1.添加依賴(消費者也要添加客戶端依賴)
2.配置文件(消費者也要添加到服務)
3.修改url
路徑(服務拉取)
String url = "http://user-service/user/"+order.getUserId();User user = restTemplate.getForObject(url,User.class);order.setUser(user);
4.負載均衡@LoadBalanced
//配置類注冊restTemplate的bean@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
2.3.Eureka和Ribbon
Eureka是一個服務注冊和發現的組件,Ribbon是一個負載均衡的組件。
負載均衡流程
2.3.1.Ribbon負載均衡策略
負載均衡的規則都定義在IRule接口中,而IRule有很多不同的實現類:
不同規則的含義如下:
內置負載均衡規則類 | 規則描述 |
---|---|
RoundRobinRule | 簡單輪詢服務列表來選擇服務器。它是Ribbon默認的負載均衡規則。 |
AvailabilityFilteringRule | 對以下兩種服務器進行忽略: (1)在默認情況下,這臺服務器如果3次連接失敗,這臺服務器就會被設置為“短路”狀態。短路狀態將持續30秒,如果再次連接失敗,短路的持續時間就會幾何級地增加。 (2)并發數過高的服務器。如果一個服務器的并發連接數過高,配置了AvailabilityFilteringRule規則的客戶端也會將其忽略。并發連接數的上限,可以由客戶端的..ActiveConnectionsLimit屬性進行配置。 |
WeightedResponseTimeRule | 為每一個服務器賦予一個權重值。服務器響應時間越長,這個服務器的權重就越小。這個規則會隨機選擇服務器,這個權重值會影響服務器的選擇。 |
ZoneAvoidanceRule | 以區域可用的服務器為基礎進行服務器的選擇。使用Zone對服務器進行分類,這個Zone可以理解為一個機房、一個機架等。而后再對Zone內的多個服務做輪詢。 |
BestAvailableRule | 忽略那些短路的服務器,并選擇并發數較低的服務器。 |
RandomRule | 隨機選擇一個可用的服務器。 |
RetryRule | 重試機制的選擇邏輯 |
默認的實現就是ZoneAvoidanceRule,是一種輪詢方案
2.3.2.Ribbon負載均衡配置
兩種方式的區別:
- 代碼方式:全局配置,所有order的服務者都是這個配置,
- 配置文件方式:給某個微服務配置負載均衡規則,比如只配置userservice服務
- 代碼方式:在order-service中的OrderApplication類中,定義一個新的IRule:
@Bean
public IRule randomRule(){return new RandomRule();
}
- 配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改規則:
userservice: # 給某個微服務配置負載均衡規則,這里是userservice服務ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 負載均衡規則
注意,一般用默認的負載均衡規則,不做修改。
2.3.3.饑餓加載
默認是懶加載:第一次使用才加載LoadBalanceClient
饑餓加載:啟動即加載
ribbon:eager-load:clients: - user-service # 指定饑餓加載的服務名稱,多個就換行加 -enabled: true # 開啟饑餓加載
3.Nacos注冊中心
Nacos是阿里巴巴的產品,現在是SpringCloud中的一個組件。相比Eureka功能更加豐富,在國內受歡迎程度較高。
3.1.服務注冊到nacos
在Nacos的GitHub頁面,提供有下載鏈接,可以下載編譯好的Nacos服務端或者源代碼:
GitHub主頁:https://github.com/alibaba/nacos
GitHub的Release下載頁:https://github.com/alibaba/nacos/releases
下載解壓到無中文無空格的目錄下,
啟動:cmd命令
startup.cmd -m standalone
1.引入依賴
在cloud-demo父工程的pom文件中的<dependencyManagement>
中引入SpringCloudAlibaba的依賴:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.5.RELEASE</version><type>pom</type><scope>import</scope>
</dependency>
然后在user-service和order-service中的pom文件中引入nacos-discovery依賴:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
注意:不要忘了注釋掉eureka的依賴。
2.配置nacos地址
在user-service和order-service的application.yml中添加nacos地址:
spring:cloud:nacos:server-addr: localhost:8848
注意:不要忘了注釋掉eureka的地址
3.2.服務分級存儲模型
一個服務有多個實例,同一個機房內的實例,劃分為一個集群
一級:集群
二級:服務
三級:實例
3.2.1.配置集群
方法一:
修改user-service的application.yml文件,添加集群配置:
spring:cloud:nacos:server-addr: localhost:8848discovery:cluster-name: HZ # 集群名稱
修改一個集群,啟動對應實例,再修改集群,再啟動實例,即可實現集群劃分配置。
方法二:
也可以修改服務的VM選項
-Dserver.port=8083 -Dspring.cloud.nacos.discovery.cluster-name=SH
3.2.2.配置同集群優先的負載均衡
1.給消費者添加集群
spring:cloud:nacos:server-addr: localhost:8848discovery:cluster-name: HZ # 集群名稱
2.在消費者yml
文件中修改負載均衡規則
userservice:ribbon:NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 負載均衡規則
3.3.配置權重
- 權重在可以設置在0~1之間
- 權重越高,被訪問的越多
- 權重為零,不會被訪問
3.4.環境隔離
Nacos提供了namespace來實現環境隔離功能。例如開發環境和生產環境隔離
- nacos中可以有多個namespace
- namespace下可以有group、service等
- 不同namespace之間相互隔離,例如不同namespace的服務互相不可見
- 每個namespace有唯一的id
在yml文件中,添加namespace
的id
spring:cloud:nacos:server-addr: localhost:8848discovery:cluster-name: HZnamespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 # 命名空間,填ID
3.5.Eureka和nacos的區別
-
Nacos與eureka的共同點
- 都支持服務注冊和服務拉取
- 都支持服務提供者心跳方式做健康檢測
-
Nacos與Eureka的區別
- Nacos支持服務端主動檢測提供者狀態:臨時實例采用心跳模式,非臨時實例采用主動檢測模式
- 臨時實例心跳不正常會被剔除,非臨時實例則不會被剔除
- Nacos支持服務列表變更的消息推送模式,服務列表更新更及時
- Nacos集群默認采用AP(強調服務可用性)方式,當集群中存在非臨時實例時,采用CP(強調數據可靠性和一致性)模式;Eureka采用AP方式
Nacos的服務實例分為兩種l類型:
-
臨時實例:如果實例宕機超過一定時間,會從服務列表剔除,默認的類型。
-
非臨時實例:如果實例宕機,不會從服務列表剔除,也可以叫永久實例。
配置一個實例為永久實例,yml文件添加以下配置
spring:cloud:nacos:discovery:ephemeral: false # 設置為非臨時實例