零基礎學Java——第十一章:實戰項目 - 微服務入門

第十一章:實戰項目 - 微服務入門

隨著互聯網應用的復雜性不斷增加,單體應用(Monolithic Application)在可擴展性、可維護性、技術棧靈活性等方面逐漸暴露出一些問題。微服務架構(Microservices Architecture)應運而生,成為構建大型復雜應用的一種流行方式。

1. 什么是微服務?

微服務是一種架構風格,它將一個大型復雜應用拆分成一組小型的、獨立部署的服務。每個服務都圍繞特定的業務能力構建,并且可以獨立開發、測試、部署和擴展。

核心思想

  • 單一職責:每個微服務只關注一項特定的業務功能。
  • 獨立部署:每個微服務都可以獨立部署,不依賴于其他服務的部署周期。
  • 技術異構性:不同的微服務可以使用不同的編程語言、數據庫或技術棧。
  • 去中心化治理:團隊可以獨立負責自己的服務,包括技術選型和數據管理。
  • 彈性與容錯:單個服務的故障不會導致整個系統崩潰。

生活中的例子

想象一個大型電商平臺。如果采用單體架構,所有的功能(用戶管理、商品管理、訂單管理、支付、庫存等)都在一個巨大的代碼庫中。如果采用微服務架構,這些功能會被拆分成獨立的服務:

  • 用戶服務 (User Service)
  • 商品服務 (Product Service)
  • 訂單服務 (Order Service)
  • 支付服務 (Payment Service)
  • 庫存服務 (Inventory Service)

這些服務之間通過輕量級的通信機制(通常是HTTP/REST API或消息隊列)進行交互。

2. 微服務與單體應用的對比

特性單體應用 (Monolithic)微服務 (Microservices)
代碼庫單一、龐大多個、小型、獨立
部署整個應用作為一個單元部署每個服務獨立部署
擴展性整體擴展,難以針對特定功能進行精細化擴展可針對每個服務獨立擴展
技術棧通常統一技術棧不同服務可采用不同技術棧
開發效率初期快,后期因代碼耦合和復雜性增加而變慢初期可能較慢(需要處理分布式問題),后期因獨立性而提高
容錯性單點故障可能導致整個應用不可用單個服務故障影響范圍有限,系統更具彈性
團隊協作大型團隊在單一代碼庫上協作可能存在沖突和瓶頸小型自治團隊負責各自服務,并行開發效率高
復雜性應用內部復雜性高分布式系統帶來的運維和管理復雜性高

3. 微服務的優勢

  • 技術多樣性:可以為每個服務選擇最適合的技術棧。
  • 彈性伸縮:可以根據每個服務的負載情況獨立進行伸縮。
  • 易于維護和理解:每個服務代碼量小,業務邏輯清晰。
  • 獨立部署,快速迭代:單個服務的修改和部署不影響其他服務,可以更快地交付新功能。
  • 更好的故障隔離:一個服務的故障不會輕易導致整個系統癱瘓。
  • 團隊自治:小型團隊可以獨立負責一個或多個服務,提高開發效率和責任感。

4. 微服務的挑戰

  • 分布式系統復雜性:需要處理網絡延遲、服務間通信、數據一致性等問題。
  • 運維成本:需要管理和監控大量的服務實例,對自動化運維能力要求高。
  • 測試復雜性:端到端測試和集成測試變得更加復雜。
  • 服務發現與注冊:需要機制來動態發現和注冊服務實例。
  • 配置管理:需要統一管理各個服務的配置。
  • 鏈路追蹤與監控:需要工具來追蹤跨多個服務的請求,并監控系統健康狀況。
  • 數據一致性:在分布式環境中保證數據最終一致性是一個挑戰。

5. Java 微服務技術棧概覽

Java生態系統為構建微服務提供了豐富的框架和工具。

5.1 Spring Boot

Spring Boot是構建Java微服務的首選框架。它簡化了Spring應用的創建和部署,并且內置了對常見微服務模式的支持。

5.2 Spring Cloud

Spring Cloud是基于Spring Boot的一系列框架的有序集合,用于快速構建分布式系統中的一些常見模式(例如,配置管理、服務發現、斷路器、智能路由、微代理、控制總線、一次性令牌、全局鎖、領導選舉、分布式會話、集群狀態)。

Spring Cloud 核心組件

  • 服務發現與注冊 (Service Discovery & Registration)
    • Netflix Eureka (維護模式,推薦使用Consul或Nacos)
    • HashiCorp Consul
    • Alibaba Nacos
  • 客戶端負載均衡 (Client-side Load Balancing)
    • Netflix Ribbon (維護模式,Spring Cloud LoadBalancer是推薦替代方案)
    • Spring Cloud LoadBalancer
  • 聲明式REST客戶端 (Declarative REST Client)
    • Netflix Feign (現在是OpenFeign)
    • Spring Cloud OpenFeign
  • API網關 (API Gateway)
    • Netflix Zuul (Zuul 1維護模式,Zuul 2不被Spring Cloud直接支持)
    • Spring Cloud Gateway (推薦)
  • 斷路器 (Circuit Breaker)
    • Netflix Hystrix (維護模式)
    • Resilience4j (推薦)
    • Sentinel (Alibaba)
  • 配置中心 (Configuration Management)
    • Spring Cloud Config Server
    • HashiCorp Consul
    • Alibaba Nacos
  • 消息總線 (Message Bus)
    • Spring Cloud Bus (通常與Spring Cloud Config配合使用,實現配置動態刷新)
  • 分布式追蹤 (Distributed Tracing)
    • Spring Cloud Sleuth (通常與Zipkin或Jaeger集成)

6. 構建一個簡單的微服務示例 (使用 Spring Boot)

讓我們構思兩個簡單的微服務:一個“問候服務”(Greeting Service)和一個“用戶服務”(User Service)。“問候服務”會調用“用戶服務”來獲取用戶名,然后返回個性化的問候語。

6.1 創建用戶服務 (User Service)

  1. 使用 Spring Initializr 創建項目:
    • Group: com.example.microservices
    • Artifact: user-service
    • Dependencies: Spring Web
  2. 創建 User POJO:
    package com.example.microservices.userservice;public class User {private Long id;private String username;public User(Long id, String username) {this.id = id;this.username = username;}// Getters and Setterspublic Long getId() { return id; }public void setId(Long id) { this.id = id; }public String getUsername() { return username; }public void setUsername(String username) { this.username = username; }
    }
    
  3. 創建 UserController:
    package com.example.microservices.userservice;import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
    import java.util.Map;@RestController
    @RequestMapping("/users")
    public class UserController {private final Map<Long, User> users = new HashMap<>();public UserController() {users.put(1L, new User(1L, "Alice"));users.put(2L, new User(2L, "Bob"));}@GetMapping("/{id}")public User getUserById(@PathVariable Long id) {System.out.println("User Service: Received request for user ID: " + id);return users.getOrDefault(id, new User(0L, "Unknown"));}
    }
    
  4. 配置端口 (可選,避免沖突): 在 application.properties 中設置:
    server.port=8081
    
  5. 運行 User Service.
    測試:訪問 http://localhost:8081/users/1,應返回 {"id":1,"username":"Alice"}

6.2 創建問候服務 (Greeting Service)

  1. 使用 Spring Initializr 創建項目:
    • Group: com.example.microservices
    • Artifact: greeting-service
    • Dependencies: Spring Web, Spring Boot Actuator (可選,用于健康檢查等)
  2. 創建 User DTO (Data Transfer Object) (用于接收來自User Service的數據):
    package com.example.microservices.greetingservice;// 這個類結構需要和User Service返回的User對象一致
    public class User {private Long id;private String username;// Getters and Setterspublic Long getId() { return id; }public void setId(Long id) { this.id = id; }public String getUsername() { return username; }public void setUsername(String username) { this.username = username; }
    }
    
  3. 創建 GreetingController:
    package com.example.microservices.greetingservice;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 org.springframework.web.client.RestTemplate;@RestController
    public class GreetingController {// RestTemplate用于進行HTTP調用private final RestTemplate restTemplate;@Autowiredpublic GreetingController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}@GetMapping("/greet/{userId}")public String greetUser(@PathVariable Long userId) {System.out.println("Greeting Service: Received request for user ID: " + userId);// 調用User Service獲取用戶信息// 注意:這里硬編碼了User Service的地址,實際項目中應使用服務發現String userServiceUrl = "http://localhost:8081/users/" + userId;User user = restTemplate.getForObject(userServiceUrl, User.class);if (user != null && !"Unknown".equals(user.getUsername())) {return "Hello, " + user.getUsername() + "!";} else {return "Hello, Anonymous User!";}}
    }
    
  4. 配置 RestTemplate Bean (在主應用類中添加):
    package com.example.microservices.greetingservice;import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;@SpringBootApplication
    public class GreetingServiceApplication {public static void main(String[] args) {SpringApplication.run(GreetingServiceApplication.class, args);}@Bean // 將RestTemplate注冊為一個Bean,Spring會管理它的生命周期public RestTemplate restTemplate() {return new RestTemplate();}
    }
    
  5. 配置端口: 在 application.properties 中設置 (例如 server.port=8082)。
  6. 運行 Greeting Service.
    測試:訪問 http://localhost:8082/greet/1。Greeting Service會調用User Service,然后返回 Hello, Alice!
    如果User Service未運行或ID不存在,可能會返回 Hello, Anonymous User! 或報錯。

注意:這個例子非常基礎,它硬編碼了服務地址。在實際的微服務架構中,你需要使用服務發現機制(如Eureka, Consul, Nacos)和客戶端負載均衡(如Spring Cloud LoadBalancer)來動態查找和調用服務。

7. 服務發現與注冊 (以 Nacos 為例,概念性介紹)

當微服務數量增多,手動管理它們的地址和端口變得不現實。服務發現與注冊中心解決了這個問題。

  • 服務注冊:每個微服務實例在啟動時,向注冊中心注冊自己的網絡位置(IP地址、端口號)和其他元數據。
  • 服務發現:當一個服務(如Greeting Service)需要調用另一個服務(如User Service)時,它會向注冊中心查詢User Service的可用實例列表。
  • 健康檢查:注冊中心會定期檢查已注冊服務的健康狀況,并剔除不健康的實例。

Alibaba Nacos 是一個功能豐富的平臺,提供服務發現、配置管理和服務管理。

大致流程

  1. 啟動 Nacos Server
  2. User Service 配置:
    • 添加 Nacos Discovery Starter 依賴 (spring-cloud-starter-alibaba-nacos-discovery)。
    • application.properties 中配置 Nacos Server 地址和應用名:
      spring.application.name=user-service
      spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
      
    • 在主類上添加 @EnableDiscoveryClient 注解。
  3. Greeting Service 配置:
    • 添加 Nacos Discovery Starter 依賴。
    • 配置 Nacos Server 地址和應用名 (spring.application.name=greeting-service)。
    • 在主類上添加 @EnableDiscoveryClient 注解。
    • 修改 RestTemplate Bean,添加 @LoadBalanced 注解,使其能夠通過服務名進行調用:
      @Bean
      @LoadBalanced // 開啟負載均衡
      public RestTemplate restTemplate() {return new RestTemplate();
      }
      
    • 修改 GreetingController 中調用User Service的URL,使用服務名代替硬編碼的IP和端口:
      // String userServiceUrl = "http://localhost:8081/users/" + userId; // 舊方式
      String userServiceUrl = "http://user-service/users/" + userId; // 新方式,user-service是User Service在Nacos中注冊的服務名
      

當Greeting Service通過 http://user-service/... 調用時,Spring Cloud LoadBalancer (集成了Ribbon的功能) 會從Nacos獲取 user-service 的可用實例列表,并選擇一個實例進行調用。

8. API 網關 (以 Spring Cloud Gateway 為例,概念性介紹)

當微服務數量眾多時,客戶端直接與所有微服務通信會變得復雜且難以管理。API網關作為系統的唯一入口,提供了請求路由、聚合、安全、監控等功能。

Spring Cloud Gateway 是一個基于Spring Framework 5, Project Reactor和Spring Boot 2構建的API網關。

主要功能

  • 路由 (Routing):根據請求的路徑、頭部等信息將請求轉發到后端相應的微服務。
  • 斷言 (Predicates):匹配HTTP請求中的任何內容,如路徑、方法、頭部等,用于決定路由規則是否適用。
  • 過濾器 (Filters):在請求被路由前后執行一些邏輯,如修改請求/響應、認證、限流等。

大致配置

  1. 創建一個新的Spring Boot項目,添加 Spring Cloud Gateway 依賴。
  2. application.propertiesapplication.yml 中配置路由規則:
    spring:application:name: api-gatewaycloud:gateway:discovery:locator:enabled: true # 開啟從注冊中心自動發現服務并創建路由lower-case-service-id: true # 將服務名轉為小寫作為路徑前綴routes:- id: user_service_route # 路由ID,唯一即可uri: lb://user-service # lb:// 表示從注冊中心負載均衡地選擇 user-service 實例predicates:- Path=/api/users/** # 當請求路徑匹配 /api/users/** 時,應用此路由# filters: # 可以添加過濾器# - StripPrefix=1 # 例如,去掉路徑中的第一個前綴 /api- id: greeting_service_routeuri: lb://greeting-servicepredicates:- Path=/api/greetings/**
    server:port: 8080 # 網關端口
    
    如果開啟了 discovery.locator.enabled=true,Gateway會自動為注冊中心中的每個服務創建一個路由,路徑通常是 /服務名小寫/**。例如,可以直接通過 http://localhost:8080/user-service/users/1 訪問User Service。

客戶端現在只需要與API網關 (如 http://localhost:8080) 通信,網關會將請求路由到相應的后端微服務。

9. 總結與下一步

微服務架構為構建大型、復雜的分布式系統提供了一種靈活且可擴展的方式。Spring Boot和Spring Cloud為Java開發者構建微服務提供了強大的支持。

入門微服務需要掌握的關鍵概念

  • 服務拆分原則
  • 服務間通信 (REST API, 消息隊列)
  • 服務發現與注冊
  • 客戶端負載均衡
  • API網關
  • 斷路器與容錯
  • 配置管理
  • 分布式追蹤與監控

下一步可以探索的內容

  • 深入學習 Spring Cloud 各個組件:如Nacos/Consul, OpenFeign, Resilience4j, Spring Cloud Gateway, Spring Cloud Config等。
  • 容器化與編排:學習Docker和Kubernetes,用于微服務的打包、部署和管理。
  • 消息隊列:學習RabbitMQ, Kafka等,實現異步通信和解耦。
  • 分布式事務:了解Saga模式、TCC模式等處理分布式事務的方案。
  • DevOps實踐:學習CI/CD(持續集成/持續交付)流程,實現微服務的自動化構建、測試和部署。

微服務是一個龐大且不斷發展的領域。從小處著手,逐步實踐,你會慢慢掌握它的精髓。祝你學習愉快!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/80023.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80023.shtml
英文地址,請注明出處:http://en.pswp.cn/web/80023.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

git 本地提交后修改注釋

dos命令行進入目錄&#xff0c;idea可以點擊Terminal 進入命令行 git commit --amend -m "修改內容"

Python訓練打卡Day22

復習日&#xff1a; 1.標準化數據&#xff08;聚類前通常需要標準化&#xff09; scaler StandardScaler() X_scaled scaler.fit_transform(X) StandardScaler() &#xff1a;這部分代碼調用了 StandardScaler 類的構造函數。在Python中&#xff0c;當你在類名后面加上括號…

氣動排渣煤粉爐專用V型球閥——法蘭連接耐磨閥門生產廠家解析-耀圣

氣動排渣煤粉爐專用V型球閥——法蘭連接耐磨閥門生產廠家解析 副標題&#xff1a;開關靈活無泄漏 標配行程開關/電磁閥/過濾器 一、產品概述&#xff1a;氣動排渣煤粉爐專用V型球閥核心優勢 作為專業的氣動耐磨V型球閥生產廠家&#xff0c;我們針對煤粉爐排渣工況研發的法蘭連…

Linux云計算訓練營筆記day08(MySQL數據庫)

Linux云計算訓練營筆記day08&#xff08;MySQL數據庫&#xff09; 目錄 Linux云計算訓練營筆記day08&#xff08;MySQL數據庫&#xff09;數據準備修改更新update刪除delete數據類型1.整數類型2.浮點數類型(小數)3.字符類型4.日期5.枚舉: 表頭的值必須在列舉的值里選擇拷貝表復…

致遠OA人事標準模塊功能簡介【附應用包百度網盤下載地址,官方售價4W】

人事管理應用&#xff0c;圍繞崗位配置、招聘管理、員工檔案、入轉調離、員工自助申報、數據信息管理等人力資源管理關鍵業務&#xff0c;構建全員可參與的人事工作協同平臺&#xff0c;讓人事從繁雜瑣碎的事務中解脫出來&#xff0c;高質高效工作&#xff0c;讓管理層清楚掌握…

數字孿生工廠實戰指南:基于Unreal Engine/Omniverse的虛實同步系統開發

引言&#xff1a;工業元宇宙的基石技術 在智能制造2025與工業元宇宙的交匯點&#xff0c;數字孿生技術正重塑傳統制造業。本文將手把手指導您構建基于Unreal Engine 5.4與NVIDIA Omniverse的實時數字孿生工廠系統&#xff0c;集成Kafka實現毫秒級虛實同步&#xff0c;最終交付…

【向量模型 + HNSW 參數如何選擇】

目錄 一、embedding_function&#xff08;向量模型&#xff09; 可選方式 選型建議 二、HNSW 參數選擇&#xff08;核心影響搜索速度與準確率&#xff09; 2.1 參數解釋和推薦值 2.2 配置模板參考 1、推薦默認配置&#xff08;適合大多數項目&#xff09;&#xff1a; 2…

fpga系列 HDL : Microchip FPGA開發軟件 Libero Soc 安裝 license申請

啟動 注冊賬號&#xff1a;https://login.microchip.com/申請免費許可&#xff1a;https://www.microchipdirect.com/fpga-software-products C:\Windows\System32>vol驅動器 C 中的卷是 Windows卷的序列號是 ****-****為“D:\Microsemi\License.dat”創建環境變量“LM_LICE…

【C++】解析C++面向對象三要素:封裝、繼承與多態實現機制

解析C面向對象三要素&#xff1a;封裝、繼承與多態實現機制 1. 面向對象設計基石2. 封裝&#xff1a;數據守衛者2.1 訪問控制實現2.2 封裝優勢 3. 繼承&#xff1a;代碼復用藝術3.1 繼承的核心作用3.2 繼承類型對比3.3 典型應用場景3.4 構造函數與析構函數處理3.4.1 構造順序控…

Python并發編程:開啟性能優化的大門(7/10)

1.引言 在當今數字化時代&#xff0c;Python 已成為編程領域中一顆璀璨的明星&#xff0c;占據著編程語言排行榜的榜首。無論是數據科學、人工智能&#xff0c;還是 Web 開發、自動化腳本編寫&#xff0c;Python 都以其簡潔的語法、豐富的庫和強大的功能&#xff0c;贏得了廣大…

數學復習筆記 10

前言 我覺得數學的高分乃至滿分屬于那些&#xff0c;聰明&#xff0c;堅韌&#xff0c;勇敢&#xff0c;細致的人。我非常慚愧自己不是這樣的人&#xff0c;我在生活中發現了這樣的同學&#xff0c;和他們交流的時候我常常感到汗流浹背&#xff0c;因為他們非常扎實的基礎知識…

深入理解 Webpack 核心機制與編譯流程

&#x1f916; 作者簡介&#xff1a;水煮白菜王&#xff0c;一位前端勸退師 &#x1f47b; &#x1f440; 文章專欄&#xff1a; 前端專欄 &#xff0c;記錄一下平時在博客寫作中&#xff0c;總結出的一些開發技巧和知識歸納總結?。 感謝支持&#x1f495;&#x1f495;&#…

概率相關問題

問題匯總 1. 貝葉斯定理&#xff08;貝葉斯公式和全概率公式&#xff09;2. 概率題2.1 隨機發生器的概率為1/2 1. 貝葉斯定理&#xff08;貝葉斯公式和全概率公式&#xff09; 定義&#xff1a;在信息和條件有限的情況下&#xff0c;基于過去的數據&#xff0c;通過動態調整的…

【系統架構師】2025論文《WEB系統性能優化技術》

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一個正在變禿、變強的文藝傾年。 &#x1f514;本文分享【系統架構師】2025論文《系統可靠性設計》&#xff0c;期待與你一同探索、學習、進步&#xff0c;一起卷起來叭&#xff01; 目錄 項目介紹背景介紹系統模塊技術棧性能…

ADS1220高精度ADC(TI)——應用 源碼

文章目錄 德州儀器ADS1220概述資料引腳&封裝布線寄存器配置寄存器0&#xff08;00h&#xff09;配置寄存器1&#xff08;01h&#xff09;配置寄存器2&#xff08;02h&#xff09;配置寄存器3&#xff08;03h&#xff09; 連續轉換流程驅動源碼ads1220.cads1220.h 德州儀器A…

Uniapp 安卓實現訊飛語音聽寫(復制即用)

在移動應用開發中&#xff0c;語音交互功能能夠極大提升用戶體驗&#xff0c;讓操作更加便捷自然。訊飛語音聽寫技術憑借其高準確率和穩定性&#xff0c;成為眾多開發者的選擇。本文將詳細介紹如何在 Uniapp 項目中&#xff0c;實現安卓端的訊飛語音聽寫功能&#xff0c;幫助你…

【golang】DNS 資源記錄(RR)接口

Go 中 miekg/dns 包對 DNS 資源記錄&#xff08;RR&#xff09;接口 的定義&#xff1a; type RR interface {Header() *RR_HeaderString() stringcopy() RRlen(off int, compression map[string]struct{}) intpack(...)unpack(...)parse(...)isDuplicate(r2 RR) bool }這個接…

16.2 VDMA視頻轉發實驗之模擬源

文章目錄 1 實驗任務2 系統框圖3 硬件設計3.1 IP核配置3.2 注意事項3.3 自定義IP核源碼 4 軟件設計4.1 注意事項4.2 工程源碼4.2.1 main.c文件 1 實驗任務 基于14.1&#xff0c;相較于16.1&#xff0c;使用自定義IP核vid_gen_motion替換Xilinx TPG IP核。 2 系統框圖 基于14…

深度學習之用CelebA_Spoof數據集搭建一個活體檢測-訓練好的模型用MNN來推理

一、模型轉換準備 首先確保已完成PyTorch到ONNX的轉換&#xff1a;深度學習之用CelebA_Spoof數據集搭建活體檢測系統&#xff1a;模型驗證與測試。這里有將PyTorch到ONNX格式的模型轉換。 二、ONNX轉MNN 使用MNN轉換工具進行格式轉換&#xff1a;具體的編譯過程可以參考MNN的…

JVM學習專題(一)類加載器與雙親委派

目錄 1、JVM加載運行全過程梳理 2、JVM Hotspot底層 3、war包、jar包如何加載 4、類加載器 我們來查看一下getLauncher&#xff1a; 1.我們先查看getExtClassLoader() 2、再來看看getAppClassLoader(extcl) 5、雙親委派機制 1.職責明確&#xff0c;路徑隔離?&#xff…