远程调用服务实战

简介: 本章节中需要有三个角色:服务注册中心(对应前文中我们的eureka子模块)、服务提供者(对应前文中我们的eureka-hi子模块)、服务消费者,其中服务注册中心就是我们上一篇的eureka单机版启动既可,流程是首先启动注册中心,服务提供者生产服务并注册到服务中心中,消费者从服务中心中获取服务并执行。


前言



欢迎来到菜鸟SpringCloud入门实战系列(SpringCloudForNoob),该系列通过层层递进的实战视角,来一步步学习和理解SpringCloud。

本系列适合有一定Java以及SpringBoot基础的同学阅读。


远程调用服务实战



本章节中需要有三个角色:服务注册中心(对应前文中我们的eureka子模块)、服务提供者(对应前文中我们的eureka-hi子模块)、服务消费者,其中服务注册中心就是我们上一篇的eureka单机版启动既可,流程是首先启动注册中心,服务提供者生产服务并注册到服务中心中,消费者从服务中心中获取服务并执行。


服务提供者:使用原来的eureka-hi子模块

子模块不需要做更改。


值得注意的是,你可以使用@EnableDiscoveryClient代替@EnableEurekaClient

两者的区别:

https://www.jianshu.com/p/f6db3117864f

注解@EnableEurekaClient上有@EnableDiscoveryClient注解,可以说基本就是EnableEurekaClient有@EnableDiscoveryClient的功能,另外上面的注释中提到,其实@EnableEurekaClientz注解就是一种方便使用eureka的注解而已,可以说使用其他的注册中心后,都可以使用@EnableDiscoveryClient注解,但是使用@EnableEurekaClient的情景,就是在服务采用eureka作为注册中心的时候,使用场景较为单一。


服务消费者:新建service-feign子模块

创建子模块service-feign,步骤和之前类似,请参考教程第一章。

修改pom.xml,引入:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
复制代码

然后在主程序引入:

@EnableFeignClients
@EnableEurekaClient
复制代码

这时候,我的springboot2.0.3又出事了,@EnableFeignClients无法引入,需要将pom.xml的引入修改为:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <!--spring boot 2.0.3版本解决方案:spring-cloud-starter-feign-->
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
复制代码

之后,修改application.yml:

server:
  # 服务端口号
  port: 8765
spring:
  application:
    # 服务名,即serviceId
    name: service-feign
eureka:
  client:
    serviceUrl:
      # 安全认证的服务注册中心地址
      defaultZone: http://localhost:8761/eureka
复制代码


远程调用

首先回顾一下eureka-hi的方法,它提供了一个上述eureka-hi服务提供了一个RESTful风格的接口:

/** 获取端口号 */
@Value("${server.port}")
String port;
/**
 * 定义一个简单接口
 * @param name
 * @return
 */
@GetMapping("/hi/{name}")
public String home(@PathVariable String name){
    return "hi " + name + ",I am from service-hi, port :" + port;
}
复制代码
  • 行为:GET
  • 资源:/hi/{name}

编写调用eureka-hi提供的接口的本地接口ServiceHi.java,如下:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
 * <p>一个Feign服务消费者接口</p>
 **/
@FeignClient(value = "service-hi")
public interface ServiceHi {
    /**
     * <p>通过Feign伪Http客户端调用service-hi提供的服务</p>
     * @author hanchao 2018/5/19 17:59
     **/
    @GetMapping("/hi/{name}")
    String sayHiFromServiceHi(@PathVariable(value = "name") String name);
}
复制代码

说明:

  • 通过@FeignClient标识当前接口是一个Feign客户端,value = "service-hi"表示其针对的是名为service-hi的服务。
  • service-hi则是我们eureka-hi子模块的spring.application.name,这个name已经在eureka注册过
  • sayHiFromServiceHi方法为伪装成HTTP客户端方法,与eureka-hi的[GET] /hi/{name}服务接口相对应。

之后,新建HelloController.java,如下:

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;
/**
 * <p>服务消费控制层</p>
 **/
@RestController
public class HelloController {
    /** 注入服务"service-hi"的Feign客户端ServiceHi */
    @Autowired
    private ServiceHi serviceHi;
    /**
     * 调用Feign客户端提供的服务,自带负载均衡
     * @param name
     * @return
     */
    @GetMapping("/hello/{name}")
    public String sayHi(@PathVariable String name){
        //调用Feign客户端ScheduleServiceHi的接口
        return serviceHi.sayHiFromServiceHi(name);
    }
}
复制代码

重点:

  • serviceHi.sayHiFromServiceHi(name)即通过Feign调用伪HTTP客户端的服务接口。

至此我们已经配置完毕,依次启动服务eureka、eureka-hi和service-feign。可以看到两个服务都已经在eureka注册:

访问 http://localhost:8765/hello/rude3knife ,即service-feign提供的服务接口。 这个服务接口会通过Feign去调用服务eureka-hi提供的服务接口,结果显示服务间调用成功。

在该调用中,我们feign并不需要指定端口号,它并不知道这个方法所在的服务提供者现在在哪个端口运行,我们只需要向eureka寻求服务。

三个模块的拓扑图如下:


测试Feign负载均衡

Feign会对服务调用进行负载平衡,我们需要同时打开两个eureka-hi服务,由于在同一台电脑上,就得把端口号从8763改为8764,然后同时开启8763和8764两个服务。

要同时运行两个端口不同的相同服务,需要在run configuration里面把allow parallle打开:

运行结构是这样的:

可以看到有两个Service-Hi进行了注册:

访问http://localhost:8765/hello/rude3knife

连续访问两次,发现两次会分别取调用eureka-hi的两个服务节点:

最后是负载平衡的拓扑图:


本章代码



https://github.com/qqxx6661/springcloud_for_noob/tree/master/04-servier-feign


参考



Spring-Cloud笔记04:服务消费者Feign

https://blog.csdn.net/hanchao5272/article/details/80574441

springcloud(三):服务提供与调用

http://www.ityouknow.com/springcloud/2017/05/12/eureka-provider-constomer.html

相关文章
|
5月前
|
Dubbo Java 应用服务中间件
从源码全面解析 dubbo 服务端服务调用的来龙去脉
从源码全面解析 dubbo 服务端服务调用的来龙去脉
|
设计模式 负载均衡 Nacos
远程调用 OpenFeign 底层原理解析
Feign 是Springcloud 提供一个声明式的伪Http客户端 它使得调用远程服务就像调用本地服务一样简单 只需要创建一个接口 并且添加注解就可以 Nacos 很好的兼容Feign Feign 默认集成了Ribbon 所以在Nacos 下使用Fegin 默认就实现了负载均衡的效果
1474 0
远程调用 OpenFeign 底层原理解析
|
2月前
|
API 数据库管理
远程调用-其他服务
远程调用-其他服务
20 1
|
4月前
|
负载均衡 前端开发 Java
openfeign远程调用的底层原理?
openfeign远程调用的底层原理?
|
8月前
|
Dubbo Java 应用服务中间件
快速上手使用Dubbo进行远程调用
本场景将对Dubbo的基础结构和使用方式进行介绍,带您体验快速上手使用Dubbo完成基础验证。
247 0
|
8月前
|
负载均衡 Dubbo Java
RPC框架-dubbo:架构及源码分析-初篇
在自学或面试dubbo时,相关的问题有很多,例如dubbo 的基本工作原理,这是使用过dubbo后应该知道的。包括dubbo的分层架构、长短链接选择、二进制协议支持;之后是使用方式(服务的注册、发现、调用方式),基础配置(超时时间、线程数),这些是最基本的。 在这些问题之后,就可以继续深入底层:关于连接方式,使用长连接还是短连接?为什么? dubbo的二进制协议支持哪些,之间有什么区别/优缺点等等,也可以考察在使用过程中遇到过哪些问题,是如何解决的。这些都需要深入理解,并且有真实、长时间使用经验。
170 0
|
消息中间件 XML JSON
一文就读懂RPC远程调用核心原理
rpc的全称是Remote Procedure Call,即远程过程调用,是分布式系统的常用通信方法。 Remote,简单来说的话就是两个不同的服务之间,两个服务肯定是两个不同的进程。因此,我们就从跨进程进行访问的角度去理解就行了。 Procedure,意思是一串可执行的代码,我们写Java的方法,就是一段课程行的代码。 Call,即调用,调用的就是跨了进程的方法。
268 0
一文就读懂RPC远程调用核心原理
|
JSON Dubbo Java
10-微服务技术栈(基础):Feign远程调用
回顾最初我们为了实现跨服务调用时,在不使用Dubbo这种RPC协议时,我们借助了RestTemplate对象实现跨服务调用,为了解决跨服务调用时调用地址写死的问题我们又引入了注册中心,从而实现根据服务名的调用。但是回过头来查看我们这段调用方法,依然存在服务地址硬编码、代码阅读性差的问题。
325 0
|
Java Nacos 开发者
使用Openfeign客户端调用微服务接口|学习笔记
快速学习使用 Openfeign 客户端调用微服务接口
160 0