应用间通信

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. CentOS 7安装Nginx 1.10.2

    安装epel-release源并进行安装 yum install epel-release yum update(时间会有点长) yum install nginx 相关操作: systemctl s ...

  2. <stdbool.h>的使用

    转载: 1.https://www.cnblogs.com/jediael/archive/2013/02/03/4304259.html 2.https://zhidao.baidu.com/que ...

  3. 如何让程序像人一样的去批量下载歌曲?Python爬取付费歌曲

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 今天来教大家一个自动化爬虫的工具 selenium selenium Se ...

  4. 【LGR-070】洛谷 3 月月赛-官方题解

    本次免费为大家提供[LGR-070]洛谷 3 月月赛的官方题解,点个赞再走呗! 代码就不上了,大家可以到别的博客上去找找!希望这篇博客能对你有所帮助!

  5. Fabric1.4.4 基础环境搭建

    简单记录一下fabric版本1.4.4的环境搭建部署,运行环境为CentOs7.8,如有错误欢迎批评指正. 1.Docker 和 Docker Compose 1. docker的安装部署 docke ...

  6. centos7.5安装gcc7.2.0

    参考https://www.cnblogs.com/lazyInsects/p/9778910.html cd /usr/src wget https://mirrors.tuna.tsinghua. ...

  7. 单源文件目录makefile

    目录结构 由于只是用来编译简单的小型程序,所以目录尽量简洁: . ├── build │   ├── bin │   ├── .dep │   └── obj ├── makefile └── src ...

  8. 【UR #12】实验室外的攻防战

    UOJ小清新题表 题目内容 依然没有粘题面主要是UOJ的题面都太长了qwq UOJ链接 一句话题意:给出两个序列 \(A\) 和 \(B\),对于 \(A\) 进行若干次操作,每次给出一个 \(i\) ...

  9. PHP SPL标准库-数据结构

    SPL是用于解决典型问题的一组接口与类的集合. 双向链表 SplDoublyLinkedList SplStack SplQueue 双链表是一种重要的线性存储结构,对于双链表中的每个节点,不仅仅存储 ...

  10. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...