2springcloud 服务调用方式

Posted llxxqq5

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2springcloud 服务调用方式相关的知识,希望对你有一定的参考价值。

RPC和HTTP

常见远程调用方式:

RPC:(Remote Produce Call)远程过程调用

 1.基于Socket
 2.自定义数据格式
 3.速度快,效率高
 4.典型应用代表:Dubbo,WebService,ElasticSearch集群间互相调用

HTTP:网络传输协议

 1.基于TCP/IP
 2.规定数据传输格式
 3.缺点是消息封装比较臃肿、传输速度比较慢
 4.优点是对服务提供和调用方式没有任何技术限定,自由灵活,更符合微服务理念

RPC和HTTP的区别:RPC是根据语言API来定义,而不是根据基于网络的应用来定义。

Http客户端工具

常见Http客户端工具:HttpClient(发送Http请求)、OKHttp(发送Http请求)、URLConnection(发送Http请求)。

2 Spring的RestTemplate

(1)RestTemplate介绍

  • RestTemplate是Rest的HTTP客户端模板工具类

  • 对基于Http的客户端进行封装

  • 实现对象与JSON的序列化与反序列化(JSON<->JavaBean)

  • 不限定客户端类型,目前常用的3种客户端都支持:HttpClient、OKHttp、JDK原生URLConnection(默认方式)

(2)RestTemplate入门案例

我们可以使用RestTemplate实现请求,resttemplate通过发送请求,请求sprovider/user/list方法。

(1)搭建provider

使用IDEA搭建一个普通的SpringBoot工程即可。

pom.xml依赖

 <!--父工程-->
 <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.1.6.RELEASE</version>
     <relativePath/> <!-- lookup parent from repository -->
 </parent>
 ​
 <dependencies>
     <!--web起步依赖-->
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
 </dependencies>

创建com.sen.bean.User

 package com.sen.bean;
 ​
 import java.io.Serializable;
 ​
 public class User implements Serializable 
     private String name;
     private String address;
     private Integer age;
 ​
     public User() 
     
 ​
     public User(String name, String address, Integer age) 
         this.name = name;
         this.address = address;
         this.age = age;
     
 ​
     public String getName() 
         return name;
     
 ​
     public void setName(String name) 
         this.name = name;
     
 ​
     public String getAddress() 
         return address;
     
 ​
     public void setAddress(String address) 
         this.address = address;
     
 ​
     public Integer getAge() 
         return age;
     
 ​
     public void setAge(Integer age) 
         this.age = age;
     
 ​
     @Override
     public String toString() 
         return "User" +
                 "name='" + name + '\\'' +
                 ", address='" + address + '\\'' +
                 ", age=" + age +
                 '';
     
 

application.yml

 server:
   port: 18081

创建com.sen.controller.UserProviderController,代码如下:

 package com.sen.controller;
 ​
 import com.sen.bean.User;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 ​
 @RestController
 @RequestMapping("/user")
 public class UserProviderController 
     @RequestMapping("/find/id")
     public User find(@PathVariable Integer id) //http://localhost:18081/user/find/1
         User user = new User();
         user.setName("fbb");
         return user;
     
 

创建启动类,并启动工程

 package com.sen;
 ​
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 ​
 @SpringBootApplication
 public class UserProvideApplication 
     public static void main(String[] args) 
         SpringApplication.run(UserProvideApplication.class, args);
     
 

访问:http://localhost:18081/user/find/1效果如下:

(2)创建resttemplate

直接使用IDEA创建一个SpringBoot工程即可。

pom.xml依赖

 <!--父工程-->
 <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.1.6.RELEASE</version>
     <relativePath/> <!-- lookup parent from repository -->
 </parent>
 ​
 <dependencies>
     <!--web起步依赖-->
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
 ​
     <!--测试包-->
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
     </dependency>
 </dependencies>

application.yml

 server:
   port: 18082

创建启动类,并在启动类中创建RestTemplate对象

 package com.sen;
 ​
 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 UserConsumerApplication 
     public static void main(String[] args) 
         SpringApplication.run(UserConsumerApplication.class, args);
     
 ​
     @Bean
     public RestTemplate restTemplate() 
         return new RestTemplate();
     
 

测试

通过RestTemplate的getForObject()方法,传递url地址及实体类的字节码

RestTemplate会自动发起请求,接收响应

并且帮我们对响应结果进行反序列化

控制器代码如下:

 package com.sen.controller;
 ​
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.client.RestTemplate;
 ​
 @RestController
 @RequestMapping("/consumer")
 public class UserConsumerController 
     @Autowired
     private RestTemplate restTemplate;
 ​
     @RequestMapping("/find")
     public String find() 
         String url = "http://localhost:18081/user/find/1";
 ​
         String json = restTemplate.getForObject(url, String.class);
         System.out.println(json);//"name":"fbb","address":null,"age":null
 ​
         return json;
     
 

 

2.3 小结

  • RPC和HTTP的区别:RPC是根据语言API来定义,而不是根据基于网络的应用来定义。

  • RestTemplate:

    ①RestTemplate是Rest的HTTP客户端模板工具类。

    ②对基于Http的客户端进行封装。

    ③实现对象与JSON的序列化与反序列化。

    ④不限定客户端类型

  • RestTemplate的使用

     创建一个RestTemplate,将该对象实例给SpringIOC容器管理
     @Bean
     public RestTemplate restTemplate()
         return new RestTemplate();
     
     ​
     restTemplate.getForObject(url,String.class);

不同服务调用方式的比较

1.同步服务调用

上图是同步调用的原理图,用户线程在完成消息序列化之后,把消息投递到通信框架,然后同步阻塞,等待通信线程发送

请求并接收到应答之后,唤醒用户同步阻塞的线程,用户线程获取到应答后返回。

2.异步服务调用

异步调用是基于JDK的Future机制,Future代表了异步操作的结果,用户可以通过调用它的get方法获取结果。

 

原理如图所示。

1.消费者调用服务端发布接口,接口调用由服务框架封装成动态代理,发起远程服务调用。

2.通信框架异步发送消息,如果没有发生I/O异常,返回。

3.消息发送成功,I/O线程构造Future对象,设置到RPC上下文中。

4.用户线程通过RPC上下文获取Future对象。

5.构造Listener对象,将其添加到Future中,用于应答服务端异步回调通知。

6.用户线程返回,不阻塞等待应答。

7.服务端返回应答消息,通信框架反序列化等。

8.I/O将应答设置到Future对象的操作结果中。

9.Future对象扫描注册监听器列表,将结果通知给监听器,监听器获取到结果之后,继续后续业务逻辑的执行。异步调用结束。

以上是关于2springcloud 服务调用方式的主要内容,如果未能解决你的问题,请参考以下文章

Spring Cloud视频教程下载

spring cloud微服务之间的调用

spring boot2X整合Consul一使用Feign实现服务调用

web service014——spring整合jaxws发布和调用CXF类型的webservice服务,拷贝服务端接口文件方式

使用Spring框架实现远程服务暴露与调用

Spring Cloud 服务之间调用