SpringCloud学习笔记二:服务间调用

微服务中,很多服务系统都在独立的进程中运行,通过各个服务系统之间的协作来实现一个大项目的所有业务功能。服务系统间 使用多种跨进程的方式进行通信协作,而RESTful风格的网络请求是最为常见的交互方式之一。

spring cloud提供的方式:

1.RestTemplate
2.Feign

一、服务提供者创建

在上一篇文章中我们介绍了服务的注册与发现,在此基础上我们将之前创建的eureka-client作为服务消费方创建一个服务提供方。

1.按照上篇文章中创建eureka-client的方式创建eureka-provider

 其中application的配置如下

#指定启动端口号
server.port=5202

#设置服务注册中心的URL,用于client和server端交流
eureka.client.service-url.defaultZone=http://localhost:5200/eureka/

#指定服务名称
spring.application.name=eureka-provide


2.创建服务提供方的ProviderController
1.在包下创建controller.ProviderController,如下图:

2.写入被调用的提供方法
package shadowcoder.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProviderController {
        @GetMapping("/hello")
        public String hello() {
            return "Hello from Eureka Provider!";
        }
}

二、RestTemplate方式调用

RestTemplate是Spring框架提供的一个工具类,主要用于简化访问RESTful服务的过程。它是从Spring3.0开始支持的一个HTTP请求工具,它封装了底层的HTTP请求细节,让我们可以以更加优雅和简洁的方式调用RESTful API。

1.启动类配置一个RestTemplate的Bean,并标记为@LoadBalanced,以便Spring Cloud能够为其添加负载均衡支持
package com.shadowcoder;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class EurekaClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaClientApplication.class, args);
	}
	@Bean
	@LoadBalanced // 使得RestTemplate具有负载均衡的能力
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}

}
2.在eureka-client包下创建controller.ConsumerController,结构如图

3.在ConsumerController写入调用服务提供者的API:/call-hello1
package com.shadowcoder.controller;

import com.netflix.appinfo.InstanceInfo;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.netflix.discovery.EurekaClient;

import java.util.List;

@RestController
public class ConsumerController {

    @Autowired
    EurekaClient client;


    private final RestTemplate restTemplate;


    @Autowired
    public ConsumerController(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder.build();
    }

    @GetMapping("/call-hello")
    public String callHello() {
        //获取服务名为eureka-provide的服务实例
        List<InstanceInfo> instances = client.getInstancesByVipAddress("eureka-provide", false);
        InstanceInfo instanceInfo = instances.get(0);
        //打印调用的接口
        System.out.println("http://" + instanceInfo.getHostName() +":"+ instanceInfo.getPort() + "/hello");
        String url = "http://" + instanceInfo.getHostName() +":"+ instanceInfo.getPort() + "/hello";
        //服务提供者的API
        String response = restTemplate.getForObject(url, String.class);
        return "Response from Service Provider: " + response;
    }

}

(备注):通过打印的调用接口发现 实际调用的是eureka的主机名而不是spring.application.name的eureka-provider

4.测试调用接口:/call-hello1

访问localhost:5201/call-hello可以发现出现成功调用了eureka-provide的/hello方法

三、Feign方式调用

Feign是一个声明式的Web服务客户端,它使得编写HTTP客户端变得更简单。在Spring Cloud中,Feign可以很容易地与Eureka等服务发现机制集成,从而实现对微服务的调用。

1.在eureka-client中添加Feign依赖
<?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>
    <parent>
        <groupId>com.shadowcoder</groupId>
        <artifactId>SpringCloudTest</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>eureka-client</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

</project>
2.启动类上添加@EnableFeignClients注解来启用Feign客户端,代码如下
package com.shadowcoder;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class EurekaClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaClientApplication.class, args);
	}
	@Bean
	@LoadBalanced // 使得RestTemplate具有负载均衡的能力
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}

}
3.包下新增一个接口service.ConsumerService

代码如下:

package com.shadowcoder.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(value = "eureka-provide")//value填写提供方的spring.application.name=eureka-provide
public interface ConsumerService {
    //提供方的调用API
    @GetMapping("/hello")
    String hello();
}
4.在ConsumerController注入ConsumerService以及写入调用服务提供者的API:/call-hello2
package com.shadowcoder.controller;

import com.netflix.appinfo.InstanceInfo;
import com.shadowcoder.service.ConsumerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.netflix.discovery.EurekaClient;

import java.util.List;

@RestController
public class ConsumerController {

    @Autowired
    EurekaClient client;
    @Autowired
    private ConsumerService consumerService;
    private final RestTemplate restTemplate;


    @Autowired
    public ConsumerController(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder.build();
    }

    @GetMapping("/call-hello")
    public String callHello() {
        //获取服务名为eureka-provide的服务实例
        List<InstanceInfo> instances = client.getInstancesByVipAddress("eureka-provide", false);
        InstanceInfo instanceInfo = instances.get(0);
        //打印调用的接口
        System.out.println("http://" + instanceInfo.getHostName() + ":" + instanceInfo.getPort() + "/hello");
        String url = "http://" + instanceInfo.getHostName() + ":" + instanceInfo.getPort() + "/hello";
        //服务提供者的API
        String response = restTemplate.getForObject(url, String.class);
        return "Response from Service Provider: " + response;
    }


    @GetMapping("/call-hello2")
    public String callHello2() {
        return "Response from Service Provider2: " + consumerService.hello();
    }


}

5.测试调用接口:/call-hello2

访问localhost:5201/call-hello2可以发现出现成功调用了eureka-provide的/hello方法

备注(提示):

1.要在启动类中加入@EnableFeignClients注解,以便Spring Cloud能够扫描到@FeignClient注解并创建Feign客户端。
2.Feign主要通过接口调用,底层实现是HttpClient或OkHttp。在定义Feign接口时,需要加入对应的Rest接口,并设置接口的参数。如果接口参数是对象或Map,应使用@RequestBody注解;如果参数是字符串,应使用@RequestParam注解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/495096.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

工厂数字化看板是什么?部署工厂数字化看板有什么作用?

随着工业4.0时代的来临&#xff0c;数字化转型已成为制造业发展的必然趋势。在这个背景下&#xff0c;工厂数字化看板作为一种高效的信息展示与管理工具&#xff0c;正逐渐受到越来越多企业的青睐。那么&#xff0c;什么是工厂数字化看板&#xff1f;部署工厂数字化看板又有哪些…

真没想到,SQL注入漏洞的这么大,竟然导致1400万名俄罗斯大学毕业生信息泄露

不知道各位面试时&#xff0c;有没有相关的面试官有没有问到这样的问题&#xff0c;什么是sql注入&#xff0c;sql注入的危害是什么&#xff0c;mybatis的#与$的区别是什么等等&#xff0c;我想很多人都知道使用mybatis的#去规避sql注入&#xff0c;但是很多人不知道其原理&…

备份SQLserver数据库到本地位置

怎么选择合适的数据库备份方案&#xff1f; 有人可能会说SSMS&#xff0c;确实&#xff0c;SSMS作为一个微软官方提供的SQLserver数据库管理工具&#xff0c;是可以帮助我们完成对数据库的备份还原任务的&#xff0c;但是它也有一些局限性&#xff0c;比如不能进行批量化的备份…

LLM应用:Prompt flow vs LangChain

背景 Prompt flow和LangChain都是LLM时代&#xff0c;为高效地构建LLM应用而生。 Prompt flow是Microsoft开源的&#xff0c;其诞生时&#xff0c;LangChain已经很有名气了。 所以作为后生的Prompt flow会为我们带来哪些新的东西呢&#xff1f; ​​​​​​​ Prompt flo…

JTW——01,简述、对比

简述、对比 一、jwt跟token的区别二、什么是jwt三、jwt能做什么四、传统的session认证五、Jwt认证 一、jwt跟token的区别 https://blog.csdn.net/wangxinxinsj/article/details/132746876 二、什么是jwt 三、jwt能做什么 四、传统的session认证 五、Jwt认证

Docker搭建LNMP环境实战(06):Docker及Docker-compose常用命令

Docker搭建LNMP环境实战&#xff08;06&#xff09;&#xff1a;Docker及Docker-compose常用命令 此处列举了docker及docker-compose的常用命令&#xff0c;一方面可以做个了解&#xff0c;另一方面可以在需要的时候进行查阅。不一定要强行记忆&#xff0c;用多了就熟悉了。 1、…

ETL工具-nifi干货系列 第五讲 处理器GenerateFlowFile

1、今天我们一起来学习处理器GenerateFlowFile。这个处理器创建带有随机数据或自定义内容的 FlowFiles。GenerateFlowFile 对于负载测试、配置和模拟非常有用。从工具栏拖动处理器到画布&#xff0c;然后选择GenerateFlowFile即可。 2、点击add按钮或者双击 GenerateFlowFile可…

大型矿业集团安全知识竞赛主持词

男&#xff1a;尊敬的各位领导&#xff0c;员工同志们&#xff1a; 合&#xff1a;大家好&#xff01; 男&#xff1b;首先让我们以热烈的掌声对公司领导亲临比赛现场指导观看表示欢迎&#xff01; 男&#xff1b;继成功开展了荣辱观专题讲座、好矿嫂女红艺术展、安全谜语竞猜…

CCF-CSP认证考试 202212-3 JPEG 解码 100分题解

更多 CSP 认证考试题目题解可以前往&#xff1a;CSP-CCF 认证考试真题题解 原题链接&#xff1a; 202212-3 JPEG 解码 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 512.0MB 问题背景 四年一度的世界杯即将画上尾声。在本次的世界杯比赛中&#xff0c;视频助理裁判&…

MySQL为什么会选错索引

在平时不知道一有没有遇到过这种情况&#xff0c;我明明创建了索引&#xff0c;但是MySQL为何不用索引呢&#xff1f;为何要进行全索引扫描呢&#xff1f; 一、对索引进行函数操作 假设现在维护了一个交易系统&#xff0c;其中交易记录表 tradelog 包含交易流水号(tradeid)、交…

计算机组成原理 — 指令系统

指令系统 指令系统指令的概述指令的格式指令的字长取决于 操作数类型和操作种类操作数的类型数据在存储器中的存放方式操作类型 寻址方式指令寻址数据寻址立即寻址直接寻址隐含寻址间接寻址寄存器寻址寄存器间接寻址基址寻址变址寻址堆栈寻址 RISC 和 CISC 技术RISC 即精简指令…

通过组策略统一开启终端系统的远程桌面,并修改远程桌面的端口号

通过组策略可以统一开启终端系统的远程桌面服务&#xff0c;但是修改远程桌面端口号则需要通过注册表或者其他方式实现&#xff0c;因为组策略本身不提供直接修改远程桌面端口的功能。以下是如何操作&#xff1a; 开启终端系统的远程桌面&#xff1a; 打开“组策略管理编辑器…

『Apisix系列』破局传统架构:探索新一代微服务体系下的API管理新范式与最佳实践

文章目录 『Apisix基石篇』『Apisix入门篇』『Apisix进阶篇』『Apisix安全篇』 『Apisix基石篇』 &#x1f680; 手把手教你从零部署APISIX高性能API网关 利用Docker-compose快速部署Apache APISIX及其依赖组件&#xff0c;实现高效的API网关搭建通过编写RPM安装脚本来自动化安…

cesium加载.tif格式文件

最近项目中有需要直接加载三方给的后缀名tif格式的文件 <script src"https://cdn.jsdelivr.net/npm/geotiff"></script> 或者 yarn add geotiff npm install geotiff 新建tifs.js import GeoTIFF, { fromBlob, fromUrl, fromArrayBuffer } from geotif…

反勒索组件的核心功能是什么

反勒索组件是一种重要的网络安全工具&#xff0c;旨在防止和应对勒索软件的攻击。勒索软件&#xff0c;通常被称为“勒索病毒”&#xff0c;是一种恶意软件&#xff0c;它会加密用户的文件并要求支付赎金以获取解密密钥。反勒索组件通过一系列的技术和策略&#xff0c;帮助用户…

操作教程|在MeterSphere中通过SSH登录服务器的两种方法

MeterSphere开源持续测试平台拥有非常强大的插件集成机制&#xff0c;用户可以通过插件实现平台能力的拓展&#xff0c;借助插件或脚本实现多种功能。在测试过程中&#xff0c;测试人员有时需要通过SSH协议登录至服务器&#xff0c;以获取某些配置文件和日志文件&#xff0c;或…

前端如何判断元素是否到达可视区域

以图片显示为例&#xff1a; window.innerHeight 是浏览器可视区的高度&#xff1b;document.body.scrollTop || document.documentElement.scrollTop 是浏览器滚动的过的距离&#xff1b;imgs.offsetTop 是元素顶部距离文档顶部的高度&#xff08;包括滚动条的距离&#xff0…

Python 从0开始 一步步基于Django创建项目(13)将数据关联到用户

在city_infos应用程序中&#xff0c;每个城市信息条目是关联到城市的&#xff0c;所以只需要将城市条目关联到用户即可。 将数据关联到用户&#xff0c;就是把‘顶层’数据关联到用户。 设计思路&#xff1a; 1、修改顶层数据模型&#xff0c;向其中添加‘用户’属性 2、根…

泛微OA 主表字段更改 修改明细字段的必填或修改属性

1、申请类型&#xff1a;其它类&#xff0c;供应商、规格、金额必填。 2、申请类型&#xff1a;IT设备类&#xff0c;供应商、规格、金额可编辑。 <script>jQuery(document).ready(function(){//绑定主表字段变更事件WfForm.bindFieldChangeEvent("field6669",…

python实战之基础篇

1. 注释 # coding utf-8 # 该注释放到文件第一行, 这个注释告诉python解释器该文件的编码集是UTF-82. 导入语句有三种形式 import <模块名> from <模块名> import <代码元素> from <模块名> import <代码元素> as <代码元素别名>3. 获取…