同步通訊涉及即時交互,其中一個服務向另一個服務發送請求並暫停其操作,直到收到回應。 REST API 和 gRPC 是用於促進此類通訊的常用協定。
RESTful API(表述性狀態傳輸)是微服務系統中服務相互通訊最常用的方法之一。 REST 利用 HTTP/HTTPS 和 JSON 或 XML 格式進行資料交換。
通常,服務透過直接呼叫另一個服務的 API 來相互互動。
請求與回應範例:
GET /users/12345 HTTP/1.1 Host: api.userservice.com Accept: application/json Authorization: Bearer your-access-token { "userId": "12345", "name": "Michel J", "email": "MJ@example.com", "address": "Mountain View, Santa Clara, California" }
原始碼範例
import org.springframework.web.client.RestTemplate; import org.springframework.http.ResponseEntity; public class OrderService { private final RestTemplate restTemplate = new RestTemplate(); private final String userServiceUrl = "https://api.userservice.com/users/"; public User getUserById(String userId) { String url = userServiceUrl + userId; ResponseEntity<User> response = restTemplate.getForEntity(url, User.class); return response.getBody(); } }
優點:
易於部署並與各種語言和工具整合。
能夠輕鬆使用測試和監控工具。
缺點:
由於其同步性質,對於高速要求可能效率不高。
在處理網路錯誤或斷開連線時可能會遇到困難。
gRPC,全名為Google Remote procedure Call,是一個高效能、開源的通用RPC框架。它利用 HTTP/2 進行高效的資料傳輸,並且通常依賴協定緩衝區(一種語言中立、平台中立、可擴展的機制,用於序列化結構化資料)來定義發送和接收的資料的結構。
範例,協定緩衝區的定義
syntax = "proto3"; package userservice; // Define message User message User { string userId = 1; string name = 2; string email = 3; string address = 4; } // Define service UserService service UserService { rpc GetUserById (UserIdRequest) returns (User); } // Define message UserIdRequest message UserIdRequest { string userId = 1; }
對於使用者管理服務,您應該實作一個遵循 .proto 檔案中提供的服務定義的 gRPC 伺服器。這包括建立必要的伺服器端邏輯來處理傳入的 gRPC 請求並產生適當的回應。
import io.grpc.stub.StreamObserver; import userservice.User; import userservice.UserIdRequest; import userservice.UserServiceGrpc; public class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase { @Override public void getUserById(UserIdRequest request, StreamObserver<User> responseObserver) { // Assuming you have a database to retrieve user information. User user = User.newBuilder() .setUserId(request.getUserId()) .setName("Michel J") .setEmail("MJ@example.com") .setAddress("Mountain View, Santa Clara, California") .build(); responseObserver.onNext(user); responseObserver.onCompleted(); } } import io.grpc.Server; import io.grpc.ServerBuilder; public class UserServer { public static void main(String[] args) throws Exception { Server server = ServerBuilder.forPort(9090) .addService(new UserServiceImpl()) .build() .start(); System.out.println("Server started on port 9090"); server.awaitTermination(); } }
優點:
由於使用 HTTP/2 和 Protocol Buffers,因此具有高效能和頻寬效率。
支援多種程式語言,具有良好的擴展性。
缺點:
如果服務不支援 gRPC,則需要轉換層。
部署和管理可能更加複雜。
非同步通訊是指一個服務向另一個服務發送請求,而不阻塞自己的操作以等待回覆的過程。這通常是透過訊息隊列或發布/訂閱系統來實現的。
訊息佇列系統,如 RabbitMQ 和 Apache ActiveMQ,促進服務之間的非同步通訊。
優點:
提高可擴充性和容錯能力:系統可以更好地處理增加的工作負載,且不易故障。
減少服務負載:透過解耦請求發送和接收,主要服務可以專注於處理任務,而不會被不斷的請求淹沒。
缺點:
可能需要額外的精力來管理和維護:基於佇列的系統可能更複雜,並且需要更多的資源來運作。
處理排序和確保訊息傳遞的困難:確保以正確的順序處理請求並且不丟失訊息可能是一項技術挑戰。
Pub/Sub(發布/訂閱)系統,例如 Apache Kafka 或 Google Pub/Sub,允許服務發布訊息和訂閱主題。
優點:
支援大規模、高吞吐量的資料流。
減少服務之間的依賴關係。
缺點:
需要更複雜的層來管理和監控主題和訊息。
處理訊息的排序和可靠性問題可能具有挑戰性。 ”
如果您有興趣,可以閱讀我之前關於 pub/sub 主題的文章。
訊息代理程式中的死信佇列第 1 部分
訊息代理程式中的死信佇列第 2 部分
訊息代理系統內的一致性與可靠性問題
事件驅動的通訊是指服務發出事件並且其他服務根據這些事件做出回應或採取操作。
當一個服務發出事件並等待其他服務的回應時,就會發生同步事件。
優點:
易於控制和監控事件處理過程。
缺點:
如果回應服務緩慢或遇到錯誤,可能會導致瓶頸
當服務發出事件且不需要等待立即回應時,就會發生非同步事件。
優點:
減少等待時間並提高可擴展性。
幫助服務更獨立地運作並減少相互依賴。
缺點:
需要額外的機制來確保正確及時地處理事件。
難以確保順序和處理重複事件。
微服務系統中服務之間通訊方式的選擇取決於效能需求、可靠性、系統複雜度等因素。每種方法都有自己的優點和缺點,了解這些方法將幫助您建立更有效率、更靈活的微服務系統。仔細考慮您系統的要求,選擇最適合的通訊方式。
以上是微服務系統中服務之間的通訊方式的詳細內容。更多資訊請關注PHP中文網其他相關文章!