springcloud

远程服务调用方式

1.1 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请求)。

1.2 Spring的RestTemplate

(1)RestTemplate介绍

  • RestTemplate是Rest的HTTP客户端模板工具类
  • 对基于Http的客户端进行封装
  • 实现对象与JSON的序列化与反序列化(JSON<->JavaBean)
  • 不限定客户端类型,目前常用的3种客户端都支持:HttpClient、OKHttp、JDK原生URLConnection(默认方式)

(2)RestTemplate入门案例

spring cloud 远程调用接口显示超时 springcloud远程调用方式_spring


我们可以使用RestTemplate实现上图中的请求,springcloud-day1-resttemplate通过发送请求,请求springcloud-day1-provider/user/list方法。

(1)搭建springcloud-day1-provider

这里不演示详细过程了,大家直接使用IDEA搭建一个普通的SpringBoot工程即可。

坐标

<groupId>com.qf</groupId>
<artifactId>springcloud-day1-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>

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.qd.bean.User

package com.qd.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.qd.controller.UserProviderController,代码如下:

package com.qd.controller;

import com.qd.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.qd;

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效果如下:

spring cloud 远程调用接口显示超时 springcloud远程调用方式_spring boot_02

(2)创建springcloud-day1-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.qd;

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.qd.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);
        return json;
    }
}

运行结果如下:

spring cloud 远程调用接口显示超时 springcloud远程调用方式_spring boot_03

1.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);