微服务之间相互调用

news/2024/9/10 14:47:02 标签: 微服务, 架构, 云原生

使用RESTful API进行微服务调用

服务A(调用方)

  1. 创建Spring Boot项目
    使用Spring Initializr创建一个新的Spring Boot项目,并添加以下依赖:

    • Spring Web: 用于构建Web应用和RESTful API。
    • Spring Boot DevTools: 提供开发时的热加载功能。
    • Lombok (可选): 简化Java对象的开发。
    • Spring Cloud OpenFeign: 用于简化HTTP客户端调用。
  2. 配置文件application.properties
    配置服务器端口。

    server.port=8080
    
  3. 定义Feign客户端
    Feign是一个声明式HTTP客户端,可以简化RESTful服务的调用。这里定义了一个接口ServiceBClient,用于调用服务B的API。

    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    // 定义Feign客户端,用于调用服务B的API
    @FeignClient(name = "service-b", url = "http://localhost:8081")
    public interface ServiceBClient {
        // 声明一个GET请求方法,映射到服务B的API
        @GetMapping("/api/data/{id}")
        String getDataById(@PathVariable("id") String id);
    }
    
  4. 创建控制器
    这个控制器包含一个RESTful端点,用于接收来自客户端的请求,并通过ServiceBClient调用服务B的API。

    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;
    
    @RestController
    public class ServiceAController {
    
        @Autowired
        private ServiceBClient serviceBClient;  // 注入Feign客户端
    
        // 定义一个GET请求方法,调用服务B的API并返回结果
        @GetMapping("/service-a/data/{id}")
        public String getDataFromServiceB(@PathVariable String id) {
            return serviceBClient.getDataById(id);
        }
    }
    
  5. 启动类
    启动Spring Boot应用并启用Feign客户端。

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    @SpringBootApplication
    @EnableFeignClients  // 启用Feign客户端
    public class ServiceAApplication {
        public static void main(String[] args) {
            SpringApplication.run(ServiceAApplication.class, args);  // 启动应用
        }
    }
    

服务B(被调用方)

  1. 创建Spring Boot项目
    使用Spring Initializr创建一个新的Spring Boot项目,并添加以下依赖:

    • Spring Web: 用于构建Web应用和RESTful API。
    • Spring Boot DevTools: 提供开发时的热加载功能。
    • Lombok (可选): 简化Java对象的开发。
  2. 配置文件application.properties
    配置服务器端口。

    server.port=8081
    
  3. 创建控制器
    这个控制器包含一个RESTful端点,用于接收来自服务A的请求,并返回相应的数据。

    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class ServiceBController {
    
        // 定义一个GET请求方法,返回ID对应的数据
        @GetMapping("/api/data/{id}")
        public String getData(@PathVariable String id) {
            return "Data from Service B with ID: " + id;
        }
    }
    
  4. 启动类
    启动Spring Boot应用。

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class ServiceBApplication {
        public static void main(String[] args) {
            SpringApplication.run(ServiceBApplication.class, args);  // 启动应用
        }
    }
    

使用gRPC进行微服务调用

服务A(调用方)

  1. 创建Spring Boot项目
    使用Spring Initializr创建一个新的Spring Boot项目,并添加以下依赖:

    • Spring Boot DevTools: 提供开发时的热加载功能。
    • Spring Boot Starter: 提供Spring Boot核心依赖。
    • gRPC Starter: 提供gRPC支持。
  2. 生成gRPC代码
    定义.proto文件并使用protoc编译生成Java代码。

    syntax = "proto3";
    
    package com.example.grpc;
    
    // 定义gRPC服务
    service DataService {
        // 定义一个RPC方法
        rpc GetData (DataRequest) returns (DataResponse);
    }
    
    // 定义请求消息
    message DataRequest {
        string id = 1;
    }
    
    // 定义响应消息
    message DataResponse {
        string data = 1;
    }
    
  3. 创建gRPC客户端
    这个服务类包含一个gRPC客户端,用于连接到服务B并调用其方法。

    import com.example.grpc.DataServiceGrpc;
    import com.example.grpc.DataRequest;
    import com.example.grpc.DataResponse;
    import io.grpc.ManagedChannel;
    import io.grpc.ManagedChannelBuilder;
    import org.springframework.stereotype.Service;
    
    @Service
    public class GrpcClientService {
    
        private final DataServiceGrpc.DataServiceBlockingStub stub;
    
        public GrpcClientService() {
            // 创建一个gRPC通道,连接到服务B
            ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 9090)
                .usePlaintext()
                .build();
            // 创建一个阻塞式的gRPC客户端
            stub = DataServiceGrpc.newBlockingStub(channel);
        }
    
        // 调用服务B的gRPC方法
        public String getData(String id) {
            DataRequest request = DataRequest.newBuilder().setId(id).build();
            DataResponse response = stub.getData(request);
            return response.getData();
        }
    }
    
  4. 创建控制器
    这个控制器包含一个RESTful端点,用于接收来自客户端的请求,并通过GrpcClientService调用服务B的gRPC服务。

    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;
    
    @RestController
    public class ServiceAController {
    
        @Autowired
        private GrpcClientService grpcClientService;  // 注入gRPC客户端服务
    
        // 定义一个GET请求方法,调用服务B的gRPC方法并返回结果
        @GetMapping("/service-a/data/{id}")
        public String getDataFromServiceB(@PathVariable String id) {
            return grpcClientService.getData(id);
        }
    }
    
  5. 启动类
    启动Spring Boot应用。

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class ServiceAApplication {
        public static void main(String[] args) {
            SpringApplication.run(ServiceAApplication.class, args);  // 启动应用
        }
    }
    

服务B(被调用方)

  1. 创建Spring Boot项目
    使用Spring Initializr创建一个新的Spring Boot项目,并添加以下依赖:

    • Spring Boot DevTools: 提供开发时的热加载功能。
    • Spring Boot Starter: 提供Spring Boot核心依赖。
    • gRPC Starter: 提供gRPC支持。
  2. 生成gRPC代码
    定义.proto文件并使用protoc编译生成Java代码(同上)。

  3. 实现gRPC服务
    这个服务类实现了gRPC服务,处理来自服务A的请求并返回响应数据。

    import com.example.grpc.DataServiceGrpc;
    import com.example.grpc.DataRequest;
    import com.example.grpc.DataResponse;
    import io.grpc.stub.StreamObserver;
    import net.devh.boot.grpc.server.service.GrpcService;
    
    @GrpcService
    public class GrpcDataService extends DataServiceGrpc.DataServiceImplBase {
    
        // 实现gRPC服务的方法
        @Override
        public void getData(DataRequest request, StreamObserver<DataResponse> responseObserver) {
            String id = request.getId();
            DataResponse response = DataResponse.newBuilder()
                .setData("Data from Service B with ID: " + id)
                .build();
            // 返回响应数据
            responseObserver.onNext(response);
            responseObserver.onCompleted();
        }
    }
    
  4. 启动类
    启动Spring Boot应用。

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class ServiceBApplication {
        public static void main(String[] args) {
            SpringApplication.run(ServiceBApplication.class, args);  // 启动应用
        }
    }
    

优点和适用场景:

  • RESTful API

    • 易于理解和使用。
    • 广泛支持各种客户端和工具。
    • 适合简单的请求/响应模式。
  • gRPC

    • 高性能、低延迟。
    • 支持多种语言。
    • 适合需要高效通信的场景,尤其是需要双向流和复杂数据交换的场景。

http://www.niftyadmin.cn/n/5640961.html

相关文章

Node.js的express模块

一、express介绍 express 是一个基于 Node.js 平台的极简、灵活的 WEB 应用开发框架 官方网址&#xff1a;https://www.expressjs. com.cn/ 简单来说&#xff0c;express 是一个封装好的工具包&#xff0c;封装了很多功能&#xff0c;便于我们开发 WEB 应用&#xff08;HTTP …

C语言:刷题笔记

一、进制转换 链接&#xff1a;小乐乐与进制转换_牛客题霸_牛客网 描述 小乐乐在课上学习了二进制八进制与十六进制后&#xff0c;对进制转换产生了浓厚的兴趣。因为他的幸运数字是6&#xff0c;所以他想知道一个数表示为六进制后的结果。请你帮助他解决这个问题。 输入描述&a…

MySQL 自学笔记(入门基础篇,含示例)

目录 一、基础1.变量2.运算符 二、数据库与表1.创建数据库2.表的增删与修改&#xff08;1&#xff09;表的创建与删除&#xff08;2&#xff09;表的修改&#xff08;3&#xff09;其他指令 3.属性约束4.数据操作&#xff08;1&#xff09;数据更新&#xff08;2&#xff09;数…

您知道tar、xz、zip这三种不同压缩方式的区别吗?

tar、xz、zip是三种不同的压缩和打包格式&#xff0c;它们在压缩算法、使用场景、兼容性等方面存在一定的差异。以下是对这三种格式的比较&#xff1a; 1. 压缩算法 tar&#xff1a;tar本身并不进行压缩&#xff0c;它只是一种打包工具&#xff0c;将多个文件和目录打包成一个…

Vue封装的过度与动画(transition-group、animate.css)

目录 1. Vue封装的过度与动画1.1 动画效果11.2 动态效果21.3 使用第三方动画库animate.css 1. Vue封装的过度与动画 作用&#xff1a;在插入、更新或移除DOM元素时&#xff0c;在合适的时候给元素添加样式类名 1.1 动画效果1 Test1.vue: transition内部只能包含一个子标签。…

C++ | Leetcode C++题解之第389题找不同

题目&#xff1a; 题解&#xff1a; class Solution { public:char findTheDifference(string s, string t) {int ret 0;for (char ch: s) {ret ^ ch;}for (char ch: t) {ret ^ ch;}return ret;} };

vue项目 / 资产管理

参考&#xff1a; https://blog.csdn.net/A_Common_Man/article/details/124601367 App.vue <template><div id"app"><div class container><h4 style"text-align: center; margin-top: 20px">资产管理</h4> <table …

SpringBoot3 + Spring Security6认证授权

SpringBoot3 Spring Security6 实现默认地址/login的认证 Spring Security 核心技术过滤器。一个web请求会经过一系列的过滤器进行认证授权。 主要是用默认的/login请求&#xff0c;继承UsernamePasswordAuthenticationFilter&#xff0c;来实现用户名和密码登录。 核心流程 …