SpringCloud 微服務分布式
軟體行業分類:
傳統軟體行業
互聯網軟體行業

軟體架構分類:
微服務
單體架構
單體應用
一個歸檔包(可以是JAR、WAR、EAR或其它歸檔格式)包含所有功能的應用程式,通常稱為
單體應用,
優點
- 便于共享: 單個歸檔檔案包含所有功能,便于在團隊之間以及不同的部署階段之間共享,
- 易于測驗:
單體應用一旦部署,所有的服務或特性就都可以使用了,這簡化了測驗程序,
因為沒有額外的依賴,每項測驗都可以在部署完成后立刻開始,- 易于部署: 只需將單個歸檔檔案復制到單個目錄下,
缺點
- 復雜性高:
由于是單個歸檔檔案,所以一個檔案 等于 整個專案,檔案包含的模塊非常多,導致模塊的邊界模糊,
依賴關系不清晰、代碼的質量參差不齊,混亂的堆在一起,使得整個專案非常復雜,
以致每次修改代碼,都非常小心,可能添加一個簡單的功能,或者修改一個Bug都會帶來隱藏的缺陷,- 技術債務:
隨著時間的推移、需求的變更和技術人員的更替,會逐漸形成應用程式的技術債務,并且越積越多,- 擴展能力受限:
單體應用只能作為一個整體進行擴展,無法根據業務模塊的需要進行伸縮,
(為了提高專案性能可以, 將一個專案復制多份部署多臺服務器~)- 阻礙技術創新:
對于單體應用來說,技術是在開發之前經過慎重評估后選定的,
每個團隊成員都必須使用相同的開發語言、持久化存盤及訊息系統,
微服務
2014 ,martin fowler馬丁·福勒
提出的:微服務架構風格 常聽的:分布式微服務
優點:
一個應用拆分為一組小型服務
每一個服務: 運行在自己的行程內,也就是可獨立部署和升級,擁有自己獨立的資料庫,通過HTTP的方式進行互通;
? 優點
? 服務圍繞業務功能拆分
? 可以由全自動部署機制獨立部署
? 微服務能夠被小團隊單獨開發,這個小團隊是2到5人的開發人員組成,
? 微服務是松耦合的,是有功能意義的服務,無論是在開發階段或部署階段都是獨立的,
? 去中心化,服務自治,服務可以使用不同的語言、不同的存盤技術;只要實作功能即可~
?微服務只是業務邏輯的代碼,不會和HTML,CSS 或其他界面組件混合,
?每個微服務都有自己的存盤能力,可以有自己的資料庫,也可以有統一資料庫,
上圖:微服務分布式架構,每一個點表示一個功能, 使用時只需要呼叫需要的功能模塊組合即可!
缺點:
- 運維要求高: 更多的服務意味著要投入更多的運維,
- 分布式固有的復雜性:
使用微服務構建的是分布式系統,對于一個分布式系統,系統容錯、網路延遲、
分布式事務等都會帶來巨大的問題,- 介面調整成本高:
微服務之間通過介面進行通信,
如果修改某一個微服務的API,可能所有用到這個介面的微服務都需要進行調整,
遠程呼叫、服務發現、負載均衡、服務容錯、配置管理、服務監控、鏈路追蹤、日志管理、任務調度……
相關概念
Provider和Consumer
分布式微服務架構中,把一個應用差分為多個 功能模塊; 每個功能模塊專注做自己的事情…
當需要實作某一功能時候, 只需要對多個需要的 功能模塊直接相互呼叫即可…
那么每個模塊即是 Provider也是Consumer(提供者和呼叫者)…
RPC和Restful
什么叫RPC
- RPC【Remote Procedure Call】是指
遠程程序呼叫
是一種行程間通信方式,他是一種技術的思想,而不是規范,
它允許程式呼叫另一個地址空間(通常是共享網路的另一臺機器上)的程序或函式,
而不用程式員顯式編碼這個遠程呼叫的細節,
即程式員無論是呼叫本地的還是遠程的函式,本質上撰寫的呼叫代碼基本相同,即網路通信
什么是REST
- REST是一種
架構風格,指的是一組架構約束條件和原則, - 滿足這些約束條件和原則的應用程式或設計就是 RESTful,
- REST規范把所有內容都視為資源,網路上一切皆資源,
- REST并沒有創造新的技術,組件或服務,只是使用Web的現有特征和能力,
- 可以完全通過HTTP協議實作,使用 HTTP 協議處理資料通信,
- REST架構對資源的操作包括獲取、創建、修改和洗掉資源的操作
正好對應HTTP協議提供的GET、POST、PUT和DELETE方法, - 這個之前學MVC時候學習過…
分布式
一個應用拆分為多個不同的功能模塊,做不同的事情!
集群
一臺服務器,承受不住某個作業,為了減輕服務器壓力,做集群 負載均價…多個設備做同一見事情!
選擇SpringCloud作為微服務
選型依據
- 整體解決方案和框架成熟度
- 社區熱度
- 可維護性
- 學習曲線
當前各大IT公司用的微服務架構有哪些?
- 阿里Dubbo/HSF
- 京東JSF
- 新浪微博Motan
- 當當網DubboX
各微服務框架對比

分布式基礎理論
什么是分布式系統?
《分布式系統原理與范型》定義:
“分布式系統是若干獨立計算機的集合,這些計算機對于用戶來說就像單個相關系統”
分布式系統(distributed system)是建立在網路之上的軟體系統,
發展演變
單一應用架構——垂直應用架構——分布式服務架構——流動計算架構

單一應用架構
當網站流量很小時,只需一個應用,將所有功能都部署在一起,
以減少部署節點和成本,此時,用于簡化增刪改查作業量的資料訪問框架(ORM)是關鍵,

適用于小型網站,小型管理系統,將所有功能都部署到一個功能里,簡單易用,
缺點:
性能擴展比較難 協同開發問題 不利于升級維護...
垂直應用架構
當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成互不相干的幾個應用
以提升效率,此時,用于加速前端頁面開發的Web框架(MVC)是關鍵,

通過切分業務來實作各個模塊獨立部署:
降低了維護和部署的難度,團隊各司其職更易管理,性能擴展也更方便,更有針對性,
缺點: 公用模塊無法重復利用,開發性的浪費
分布式服務架構
當垂直應用越來越多,應用之間互動不可避免,將核心業務抽取出來,
作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的回應多變的市場需求,
此時,用于提高業務復用及整合的分布式服務框架(RPC)是關鍵,

流動計算架構
當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,
此時需增加一個調度中心基于訪問壓力實時管理集群容量,提高集群利用率,
提高機器利用率的資源調度 和 治理中心(SOA)[ Service Oriented Architecture]是關鍵,

springClond入門 應用開發
SpringBoot和SpringCloud的區別
- SpringBoot專注于快速方便的開發單個個體微服務,
- SpringCloud是關注全域的微服務協調整理治理框架
它將SpringBoot開發的一個個單體微服務整合并管理起來:為各個微服務之間提供
配置管理、服務發現、斷路器、路由、微代理、事件總線、全域鎖、決策競選、分布式會話等等集成服務… - SpringBoot可以離開SpringCloud獨立使用開發專案,但是SpringCloud離不開SpringBoot,屬于
依賴的關系 - SpringBoot專注于快速、方便的開發單個微服務個體
- SpringCloud關注全域的服務治理框架,
搭建springcloud工程 分布式服務架構

創建一個普通的Maven專案
為了方便開發使用 Maven高級應用...開發專案:
當然你也可以不用Maven來測驗,多起幾個專案工程…
刪掉主工程的src (反之也用不上
主工程的pom.xml中加入公共依賴
<?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>
<groupId>org.example</groupId>
<artifactId>SpringCloudBJ</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<!-- Maven父工程包含管理的子工程... -->
<modules>
<module>common_api</module>
<module>common_orderService</module>
<module>common_userService</module>
</modules>
<!-- SpringBoot父依賴 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<!-- 統一設定Maven專案編碼 jdk環境 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- spring-boot的web依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring-boot的應用日志依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!-- spring-boot的單元測驗依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- lombok的依賴組件,別忘了要下載Idea lombok的插件哦~ -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 指定SpringCloud配置必要!! -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version> <!-- 版本... -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- maven的默認下載資源.. -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
關于SpringCloud版本:Greenwich
SpringCloud版本更新非常快!A B C D E F G H目前最高已經到H了我湊!!
2021年初

創建Maven子工程common_api物體模塊
主要存放專案開發所需要的物體類…

這里只有一個物體類…沒有什么太復雜的操作
Order.Java
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
@Data
@AllArgsConstructor
@RequiredArgsConstructor
//創建一個物體類: 并根據lombok 及其注解生產對應的 建構式,toString(); get/set...
public class Order {
private Integer id;
private String title;
private Double price;
private Integer uid;
}
pom.xml 不用任何添加或改動…看一下我其它Maven子工程如果呼叫;
<?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">
<parent>
<artifactId>SpringCloudBJ</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common_api</artifactId>
</project>
創建Maven子工程common_orderService訂單模塊
撰寫訂單模塊相對于的代碼…

pom.xml
<?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">
<parent>
<artifactId>SpringCloudBJ</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common_orderService</artifactId>
<!-- 關鍵!! -->
<dependencies>
<!-- common_orderService工程引入common_api -->
<dependency>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>common_api</artifactId>
</dependency>
</dependencies>
</project>
OrderService.Java
import com.wsm.entity.Order;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class OrderService {
//模擬假訂單集合...
private static List<Order> orders = new ArrayList<>();
//類加載時候默認獲取一些資料..模擬假訂單..
static {
orders.add(new Order(1, "訂單11", 10.0, 1));
orders.add(new Order(2, "訂單21", 10.0, 2));
orders.add(new Order(3, "訂單31", 10.0, 1));
orders.add(new Order(4, "訂單41", 10.0, 2));
}
//根據輸入用戶id獲取當然用訂單集合..
public List<Order> findOrderByUser(Integer uid) {
List<Order> myorders = new ArrayList<>();
//遍歷集合從中獲取 uid一致的資料存放在集合中回傳...
for (Order order : orders) {
if (order.getUid() == uid) {
myorders.add(order);
}
}
return myorders;
}
}
OrderController.Java
import com.wsm.entity.Order;
import com.wsm.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
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;
@RestController
public class OrderController {
@Autowired
private OrderService os;
//REST風格進行請求..
@GetMapping("/findOrderByUser/{uid}") //引數是以 /請求名/{引數1}/{引數2} 進行訪問的...
public List<Order> findOrderByUser(@PathVariable Integer uid){
//REST風格引數需要使用 @PathVariable獲取!!
return os.findOrderByUser(uid);
}
}
SpringBoot的主工程類:MyOrderServer.Java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyOrderServer {
public static void main(String[] args) {
SpringApplication.run(MyOrderServer.class, args);
}
}
SpringBoot application.yml組態檔
server:
port: 6001 #設定埠6001 當有多個微服務時候注意埠號可別沖突了..
spring:
application:
name: order-server #設定當然微服務名,后面的 注冊/呼叫服務,都是根據這個來的;

創建Maven子工程common_userService 用戶模塊
撰寫用戶模塊相對于的代碼…

pom.xml
<?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">
<parent>
<artifactId>SpringCloudBJ</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common_userService</artifactId>
<dependencies>
<!-- common_userService工程引入common_api -->
<dependency>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>common_api</artifactId>
</dependency>
</dependencies>
</project>
UserService.Java
@Service
@Slf4j //加載lo4g使用...
public class UserService {
@Autowired
private RestTemplate restTemplate;
//通過restTemplate進行網路通信,回傳..其它遠程模塊的資料(雖然現在都是本地的不過就是模擬了..)
public List<Order> currentUserOrder(Integer uid) {
log.info("用戶服務呼叫訂單服務");
//硬編碼的呼叫!! 這里的請求都寫死的...這好嗎?這不好...后面修改;
String myurl = "http://localhost:6001/findOrderByUser/" + uid;
log.info(myurl
);
List<Order> list = restTemplate.getForObject(myurl, List.class);
return list;
}
}
UserController.Java
//編程控制層,接受請求回應結果
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/showUserOrder")
public List<Order> showUserOrder(Integer uid){
return userService.currentUserOrder(uid); //呼叫Service層
//Service又是通過網路呼叫 訂單模塊來回應的結果,因此在此基礎上要缺點訂單模塊是運行中的...
}
}
SpringBoot的主工程類:MyUserServer.java
@SpringBootApplication
public class MyUserServer {
public static void main(String[] args) {
SpringApplication.run(MyUserServer.class, args);
}
@Bean
//實體化 RestTemplate 方便Service
//可別忘了@SpringBootApplication復合注解底層可以有@SpringBootConfiguration 它也是一個Spring的配置類!
public RestTemplate createRestTemplate() {
return new RestTemplate();
}
}
SpringBoot application.yml組態檔
server:
port: 6002 #設定埠6002 當有多個微服務時候注意埠號可別沖突了..
spring:
application:
name: user-server #設定當然微服務名,后面的 注冊/呼叫服務,都是根據這個來的;

服務呼叫
前文已經撰寫了三個基礎的微服務,在用戶下單時需要呼叫商品微服務獲取商品資料,
商品微服務提供了供人呼叫的HTTP介面
- 所以可以再下定單的時候使用http請求的相關工具類完成,
如常見的HttpClient,OkHttp,當然也可以使用Spring提供的RestTemplate
RestTemplate介紹
Spring框架提供的RestTemplate類可用于在應用中呼叫rest服務
它簡化了與http服務的通信方式,統一了RESTful的標準,封裝了http鏈接
- 我們只需要傳入url及回傳值型別即可,相較于之前常用的HttpClient,
- RestTemplate是一種更優雅的呼叫RESTful服務的方式,
- RestTemplate類的設計原則與許多其他Spring 模板類(例如JdbcTemplate、JmsTemplate)相同
為執行復雜任務提供了一種具有默認行為的簡化方法, - RestTemplate默認依賴JDK提供http連接的能力(HttpURLConnection)
如果有需要的話也可以通過setRequestFactory方法替換為例如
Apache HttpComponents、Netty或OkHttp等其它HTTP library, - 考慮到RestTemplate類是為呼叫REST服務而設計的,因此它的主要方法與REST的基礎緊密相連就不足為奇了
后者是HTTP協議的方法:HEAD、GET、POST、PUT、DELETE和OPTIONS,
RestTemplate類具有headForHeaders()、getForObject()、postForObject()、put()和delete()等方法,

硬編碼存在的問題
至此已經可以通過RestTemplate呼叫商品微服務的RESTFul API介面,
但是我們把提供者的網路地址(ip,埠)等硬編碼到了代碼中,這種做法存在許多問題:
- 應用場景有局限
- 無法動態調整
- …
那么應該怎么解決呢,就需要通過:注冊中心動態的對服務注冊和服務發現
總結
以上就是一個典型的分布式模塊架構 多模塊業務之間的相互呼叫 但↓↓↓↓
因為是用戶模塊—參考—訂單模塊
訂單是提供者provide 用戶是呼叫者Consumer
- 而如果訂單模塊服務未開啟的情況下,會影響用戶模塊的使用!
注意! - 而對應大量的模塊之間的呼叫, 隨著專案業務擴大…模塊之間的參考也會越來越復雜!!
- 而對于 A模塊服務停止 B模塊服務受影響…如果加劇呢 C模塊 D模塊…
B依賴A C依賴B D依賴C 而這時候A沒了會之間的造成服務的崩塌!!
為了解決這種問題, 注冊中心就出現了
服務注冊Eureka基礎
注冊中心可以說是微服務架構中的 ”通訊錄“,它記錄了服務和服務地址 映射關系在分布式架構中
服務會注冊到這里,當服務需要呼叫其它服務時,就這里找到服務的地址,進行呼叫,
注冊中心的主要作用
服務注冊中心是微服務架構非常重要的一個組件,在微服務架構里主要起到了協調者的一個作用,
注冊中心一般包含如下幾個功能:
- 服務發現:
提供者/呼叫者需要注冊宣告在注冊中心中才可以相互使用.
服務注冊/反注冊:保存服務提供者和服務呼叫者的資訊
服務訂閱/取消訂閱:服務呼叫者訂閱服務提供者的資訊,最好有實時推送的功能
服務路由(可選):具有篩選整合服務提供者的能力, - 服務配置:
代碼上, 服務提供者/調度者需要配置注冊中心
配置訂閱:服務提供者和服務呼叫者訂閱微服務相關的配置
配置下發:主動將配置推送給服務提供者和服務呼叫者 - 服務健康檢測
服務要定時的向注冊中心提供心跳?告訴注冊中心我還在能干活
當然注冊中心一般都有自我保護機制…
檢測服務提供者的健康情況
常見的注冊中心
- **Zookeeper **
zookeeper它是一個分布式服務框架,是Apache Hadoop 的一個子專案
它主要是用來解決分布式應用中經常遇到的一些資料管理問題,
如:統一命名服務、狀態同步服務、集群管理、分布式應用配置項的管理等,
簡單來說zookeeper=檔案系統+監聽通知機制, - Eureka
Eureka是在Java語言上,基于Restful Api開發的服務注冊與發現組件,Springcloud Netflflix中的重要組件 - Consul
Consul是由HashiCorp基于Go語言開發的支持多資料中心分布式高可用的服務發布和注冊服務軟體
采用Raft演算法保證服務的一致性,且支持健康檢查 - Nacos
Nacos是一個更易于構建云原生應用的動態服務發現、配置管理和服務管理平臺,
簡單來說 Nacos 就是注冊中心 + 配置中心的組合,提供簡單易用的特性集
幫助我們解決微服務開發必會涉及到的服務注冊與發現,服務配置,服務管理等問題,
**Nacos 還是 Spring Cloud Alibaba 組件之一,負責服務注冊與發現, **

Eureka的基本架構

Spring Cloud 封裝了 Netflix 公司開發的 Eureka
Eureka 采用了 C-S 的設計架構,Eureka Server 作為服務注冊功能的服務器,它是服務注冊中心,
- 使用 Eureka 的客戶端連接到 Eureka Server并維持心跳連接,
- 這樣系統的維護人員就可以通過 Eureka Server 來監控系統中各個微服務是否正常運行,
- Eureka包含兩個組件:
Eureka Server和Eureka Client - Eureka Server提供服務注冊
服務
各個節點啟動后,會在EurekaServer中進行注冊,
這樣EurekaServer中的服務注冊表中將會存盤所有可用服務節點的資訊,
服務節點的資訊可以在界面中直觀的看到 - EurekaClient是一個Java客戶端,用于簡化Eureka Server的互動
客戶端同時也具備一個內置的、使用輪詢(round-robin)負載演算法的負載均衡器,
在應用啟動后,將會向Eureka Server發送心跳(默認周期為30秒),
如果Eureka Server在多個心跳周期內沒有接收到某個節點的心跳,EurekaServer將會從服務注冊表中把這個服務節點移除(默認90秒)
三大角色
- Eureka Server 提供服務注冊和發現
- Service Provider服務提供方將自身服務注冊到Eureka,從而使服務消費方能夠找到
- Service Consumer 服務消費方從Eureka獲取注冊服務串列,從而能夠消費服務
使用時先啟動注冊中心——Provider提供者——Consumer呼叫者
重構SpringCloud工程 流動計算架構
基于上面的SpringCloud的分布式服務架構開發
創建Maven子工程eureka-server 注冊中心
pom.xml
<?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">
<parent>
<artifactId>SpringCloudBJ</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-server</artifactId>
<!-- Eureka-server服務依賴,必須! -->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 7001 #設定注冊中心的 埠;
spring:
application:
name: eureka-server #注冊中心應用名稱;
#配置注冊中心....
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/ #注冊中心對外暴漏的注冊地址...
#要不要去注冊中心獲取其他服務的地址,默認為true (目前只有一個注冊中心而且,當前就是注冊中心..)
fetch-registry: false
#是否將允許自己注入注冊中心,默認為true (目前只有一個注冊中心而且,當前就是注冊中心..自己注冊自己?)
register-with-eureka: false #如果一個應用中有兩個注冊中心可以開啟,達到集群注冊中心的目的...
主程式類MyEurekaServer.Java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer //注解主程式開啟 Eureka服務
public class MyEurekaServer {
public static void main(String[] args) {
SpringApplication.run(MyEurekaServer.class, args);
}
}
@EnableEurekaServer
啟動注冊中心的服務, 表示當前專案作為SpringCloud中的注冊中心
現在啟動程式就可以訪問當前的注冊中心了…

修改上面SpringBoot微服務 注冊到注冊中心中去!
common_orderService/userService注冊到注冊中心去:
加載注冊服務依賴
pom.xml
<!--- 注冊服務的依賴.. -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
主程式中加入 @EnableEurekaClient 注入注冊中心
以訂單的主程式為例子, 其它也都這么做
MyOrderServer.Java
@SpringBootApplication
@EnableEurekaClient
public class MyOrderServer {
public static void main(String[] args) {
SpringApplication.run(MyOrderServer.class, args);
}
}
@EnableEurekaClient 啟動注冊中心客戶端
表示當前主程式注冊到注冊中心去…
@EnableDiscoveryClient與@EnableEurekaClient區別
@EnableDiscoveryClient,一種為@EnableEurekaClient,用法上基本一致,
- @EnableEurekaClient是針對于 Eureka注冊中心專門的啟動注冊
注解 - @EnableDiscoveryClient在包含了@EnableEurekaClient
它是對于所以注冊中心的一個統一開啟注解…
SpringBoot .yml檔案的Eureka的配置
組態檔配置注冊中心 Eureka (以業務order的為例子)
application.yml
server:
port: 6001 #設定埠6001 當有多個微服務時候注意埠號可別沖突了..
spring:
application:
name: order-server #設定當然微服務名,后面的 注冊/呼叫服務,都是根據這個來的;
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/ #指定服務注冊的注冊中心;
instance:
prefer-ip-address: true #在Eureka上使用ip號..
instance-id: ${spring.cloud.client.ip-address}:${server.port} #在Eureka上顯示ip號..
最后別忘了把 common_userService中硬編碼解決了
UserService.Java
import com.wsm.entity.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient; //這個DiscoveryClient別搞錯
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Service
@Slf4j //加載lo4g使用...
public class UserService {
@Autowired
private RestTemplate restTemplate;
//通過restTemplate進行網路通信,回傳..其它遠程模塊的資料(雖然現在都是本地的不過就是模擬了..)
@Autowired //實作動態呼叫...
private DiscoveryClient discoveryClient;
public List<Order> currentUserOrder(Integer uid) {
//獲取注冊中心上的微服模塊實體 根據服務名;
//回傳一個集合: 有可能這個服務在多個注冊中心上存在,`負載均衡~` 所以是一個集合;
List<ServiceInstance> instances = discoveryClient.getInstances("order-server");
ServiceInstance serviceInstance = instances.get(0); //而本次只有一個...
log.info("用戶服務呼叫訂單服務");
//動態呼叫服務 服務的host 服務埠號 這個就是服務controller請求 給其引數uid
String myurl = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/findOrderByUser/" + uid;
log.info(myurl);
List<Order> list = restTemplate.getForObject(myurl, List.class);
return list;
}
}


動態的從注冊中心Eureka上獲取ip

查看這里的 ip 192.168.1.1
- windows+r
- cmd
- 輸入ipconfig

- 如果是在同一個網段下, 可以實作不同電腦通過同一個注冊中心進行使用…
但我這個不上無線局域網配置器...
Eureka的服務剔除問題
在服務客戶端Client 配置的~

默認 30秒心跳💓 90秒續約時間…
.yml
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/ #指定服務注冊的注冊中心;
instance:
prefer-ip-address: true #在Eureka上顯示ip號..
instance-id: ${spring.cloud.client.ip-address}:${server.port} #在Eureka上顯示ip號..
lease-renewal-interval-in-seconds: 5 #客戶端向注冊中心發送心跳時間
lease-expiration-duration-in-seconds: 10 #如果沒有發送心跳的延遲續約時間...
如果客戶端的服務因為某些原因關閉了,Eureka會根據心跳檢測到你沒了而移除你的服務…
- 客戶端定時向
注冊中心發送心跳如果超過時間沒有發送 默認30秒 - 會有一個延遲等待時間. 默認90秒
兩分鐘~如果還沒有啟動Eureka會把服務剔除… - 但, 因為
Eureka自我保護機制服務并不會真的 移除…而是會給你一個時間如果還沒有回來~則報錯! 
Eureka自我保護機制
一般不會關閉自我保護機制,因為如果服務又好了又可以立刻注冊會來使用...
在服務端即 注冊中心關閉保護機制,,,
注冊中心的.yml
#配置注冊中心....
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/ #注冊中心對外暴漏的注冊地址...
#要不要去注冊中心獲取其他服務的地址,默認為true (目前只有一個注冊中心而且,當前就是注冊中心..)
fetch-registry: false
#是否將允許自己注入注冊中心,默認為true (目前只有一個注冊中心而且,當前就是注冊中心..自己注冊自己?)
register-with-eureka: false #如果一個應用中有兩個注冊中心可以開啟,達到集群注冊中心的目的...
server:
enable-self-preservation: false #默認是ture 開啟的
eviction-interval-timer-in-ms: 4000 #默認是0 從不剔除!
保護機制只要關閉就會報錯!

而且只要服務失效就會移除…
nice 終于寫完了,建議三聯!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/252115.html
標籤:其他
上一篇:XXL-JOB


