应用间通信

HTTP vs RPC

  • Spring Cloud (HTTP)
  • Dubbo (RPC)

1.SpringCloud中服务间两种restful调用方式

  • RestTemplate
  • Feign

方式一、RestTemplate:是一个http客户端

RestTemplate有三种方式

1.直接写url :http://localhost:8080/msg

使用restTemplate.getForObject("http://localhost:8080/msg", String.class);方法

@RestController
@Slf4j
public class ClientController {
@GetMapping("/getProductMsg")
public String getProductMsg(){
//1. 第一种方式
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject("http://localhost:8080/msg", String.class);
log.info("response={}",response);
return response;
}
}

缺点:地址是写死的,如果对方服务有多台,这样很不好。

2.通过 ServiceInstance serviceInstance = loadBalancerClient.choose("ServerId"); 获得服务的信息。

ServerId :服务的名字

  @Autowired
private LoadBalancerClient loadBalancerClient;
@RestController
@Slf4j
public class ClientController {
@Autowired
private LoadBalancerClient loadBalancerClient; @GetMapping("/getProductMsg")
public String getProductMsg(){
//2.第二种
ServiceInstance serviceInstance= loadBalancerClient.choose("PRODUCT");
String url = String.format("http://%s:%s",serviceInstance.getHost(),serviceInstance.getPort())+"/msg";
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject(url, String.class);
log.info("response={}",response);
return response;
}
  1. 先增加@Autowired LoadBalancerClient
  2. 通过loadBalancerClient.choose("ServerId");返回一个ServiceInstance
  3. serviceInstance.getHost()、serviceInstance.getPort()可以分别获得主机以及端口号
  4. 拼接主机以及端口
  5. 通过第一种方法的restTemplate.getForObject(url, String.class)请求数据
方法 说明 返回例子
serviceInstance.getUri() 路径 http://localhost:8080
serviceInstance.getHost() 主机 localhost
serviceInstance.getServiceId() 服务id PRODUCT
serviceInstance.getPort() 端口号 8080

优点:我们可以不知道服务的路径,通过服务Id或者服务路径信息

缺点:编码比较繁琐

3.用@LoadBalanced 可在restTemplate里使用应用名字来访问

@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
@RestController
@Slf4j
public class ClientController {
@Autowired
private RestTemplate restTemplate; @GetMapping("/getProductMsg")
public String getProductMsg(){
//3.第三种方式 利用@LoadBalanced 可在restTemplate里使用应用名字
String response = restTemplate.getForObject("http://PRODUCT/msg", String.class);
log.info("response={}",response);
return response;
}
}
总结

RestTemplate有三种方式:

  1. url写死,用new RestTemplate () 访问url来获取消息
  2. 使用loadBalancerClient获取到url,然后使用new RestTemplate () 访问url 获取信息
  3. 利用@LoadBalanced注解restTemplate,然后restTemplate就可以使用应用名称来访问(通过ribbon依据某种规则,如简单轮询、随机连接去连接目标服务来实现负载均衡)

方式二、Feign

  • 本质还是http客户端
  • 声明式REST客户端(伪RPC)
  • 才用了基于接口的注解
  • 内部也使用Ribbon做负载均衡

通过feign我们能把http远程调用对开发者完全透明,得到与调用本地方法一样的编码体验

使用方法:
1.在pom中增加Feign依赖
        <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>2.0.0.M1</version>
</dependency>
2.在启动类增加注解@EnableFeignClients 开启Feign功能 (org.springframework.cloud.netflix.feign.EnableFeignClients;)
package com.imooc.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients; @SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
3.在客户端定义好要调用的服务和接口
  • 接口使用@FeignClient(name="需要调用的应用名称")
  • 方法的注解是需要调用接口的地址(也可以使用@RequestMapping、@PostMapping)

    如我们想调用的接口地址为“/order/addOrder”,且为GET请求, 那就写@GetMapping("/order/addOrder")
package com.imooc.order.client;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping; @FeignClient(name="product")
public interface ProductClient {
@GetMapping("/msg")
String productMsg();
}
4.客户端依赖注入③定义好的接口,然后直接调用即可。
package com.imooc.order.controller;

import com.imooc.order.client.ProductClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; @RestController
@Slf4j
public class ClientController {
@Autowired
private ProductClient productClient; @GetMapping("/getProductMsg")
public String getProductMsg(){
String response = productClient.productMsg();
log.info("response={}",response);
return response;
}
}

【SpringCloud】07.应用间的通信的更多相关文章

  1. 【Scala】利用Akka的actor编程模型,实现2个进程间的通信

    文章目录 步骤 一.创建maven工程,导入jar包 二.master进程代码开发 三.worker进程代码开发 四.控制台结果 步骤 一.创建maven工程,导入jar包 <propertie ...

  2. c 进程间的通信

    在上篇讲解了如何创建和调用进程 c 进程和系统调用 这篇文章就专门讲讲进程通信的问题 先来看一段下边的代码,这段代码的作用是根据关键字调用一个Python程序来检索RSS源,然后打开那个URL #in ...

  3. Directive间的通信

    Directive间的通信 源自大漠的<AngularJS>5个实例详解Directive(指令)机制 这个例子主要的难点在于如何在子Expander里面访问外层Accordion的sco ...

  4. Ucos系统任务间的通信详解

    物联网开发中,ucos系统任务间的通信是指,两个任务之间有数据的交互,具体的一起来看看吧. 1)消息邮箱 我们还是提供两个任务Task1和Task2,假设我们还是解决刚刚的问题,Task1进行按键扫描 ...

  5. Fragment间的通信

    在网上看到的一篇文章,总结的很好 为了重用Fragment的UI组件,创建的每个Fragment都应该是自包含的.有它自己的布局和行为的模块化组件.一旦你定义了这些可重用的Fragment,你就可以把 ...

  6. c# 进程间的通信实现之一简单字符串收发

       使用Windows API实现两个进程间(含窗体)的通信在Windows下的两个进程之间通信通常有多种实现方式,在.NET中,有如命名管道.消息队列.共享内存等实现方式,这篇文章要讲的是使用Wi ...

  7. Android进程间的通信之AIDL

    Android服务被设计用来执行很多操作,比如说,可以执行运行时间长的耗时操作,比较耗时的网络操作,甚至是在一个单独进程中的永不会结束的操作.实现这些操作之一是通过Android接口定义语言(AIDL ...

  8. Android进程间的通信之Messenger

    Android进程间的通信方式可以通过以下两种方式完成: Android接口定义语言(AIDL) 使用Messenger绑定服务 本文我们将学习使用Messenger绑定服务的方式进行进程间的通信. ...

  9. 第四节:Vue表单标签和组件的基本用法,父子组件间的通信

    vue表单标签和组件的基本用法,父子组件间的通信,直接看例子吧. <!DOCTYPE html> <html> <head> <meta charset=&q ...

随机推荐

  1. 【Zabbix】在CentOS 7上搭建Zabbix服务,收集Windows客户端计数器性能数据(含过程中遇到的问题解决方法)

    1.环境 1.1.关闭防火墙 命令:systemctl stop firewalld 或者 systemctl stop firewalld.service (备注:相应的,若要开启防火墙,将对应的& ...

  2. S3C6410中断系统

    S3C6410的中断主要改进是. 增加中断向量控制器,这样在S3C2440里需要用软件来跳转的中断处理机制,在S3C6410完全由硬件来跳转.你只要把ISR地址是存在连续向量寄存器空间,而不是象S3C ...

  3. Rust之路(3)——数据类型 下篇

    [未经书面同意,严禁转载] -- 2020-10-14 -- 架构是道,数据是术.道可道,非常道:术不名,不成术!道无常形,术却可循规. 学习与分析数据类型,最基本的方法就是搞清楚其存储原理,变量和对 ...

  4. rabbitmq 交换机模式一 广播模式 fanout

    <?php require_once "./vendor/autoload.php"; use PhpAmqpLib\Connection\AMQPStreamConnect ...

  5. 探索ParNew和CMS垃圾回收器

    前言 上篇文章我们一起分析了JVM的垃圾回收机制,了解了新生代的内存模型,老年代的空间分配担保原则,并简单的介绍了几种垃圾回收器.详细内容小伙伴们可以去看一下我的上篇文章:秒懂JVM的垃圾回收机制. ...

  6. vscode自定义插件安装位置

    vscode的插件默认安装位置在: C:\Users\用户名\.vscode\extensions 如果不想将插件安装在C盘,可以自定义一个目标位置存储,使用如下: 右键快捷方式,在原本的目标后加入- ...

  7. 想买保时捷的运维李先生学Java性能之 运行时数据区域

    前言 不知道自己不知道,不知道自己知道,知道自己不知道,知道自己知道,目前处于知道自己不知道这个阶段,很痛苦啊,干了4年了运维,是一个坎.越来越发觉想要走得远,还是得扎根底.   一.运行时数据区域 ...

  8. 爬虫在linux下启动selenium-安装谷歌浏览器和驱动(傻瓜式教程)

    一.升级yum(防止不必要的麻烦) yum update -y yum -y groupinstall "Development tools" yum install openss ...

  9. Django (学习第二部 ORM 模型层)

    Django对数据库的操作 Django的 ORM 简介 ORM操作 (增删改查) ORM操作数据库的增删改查 ORM创建表关系 ORM中常用字段及参数 数据库的查询优化 ORM中如何开启事务 ORM ...

  10. 如何实现 axios 的自定义适配器 adapter

    Axios 是一个非常优秀的基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中.并且提供了很多便捷的功能,例如: 支持 Promise API 拦截请求和响应 转换请求数据和 ...