5.1 服务调用

和传统的单体架构相比,分布式多了一个远程服务之间的通信,不管是 soa 还是微服务,他们本质上都是对于业务服务的提炼和复用。那么远程服务之间的调用才是实现分布式的关键因素。
image.png

5.2 实现方式

5.2.1 HTTP 应用协议的通信框架

  1. HttpURLConnection
    1. java 原生 HttpURLConnection是基于http协议的,支持get,post,put,delete等各种请求方式,最常用的就是get和post
  2. Apache Common HttpClient
    1. HttpClient 是Apache Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本。

    2. 实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
    3. 支持 HTTPS 协议
    4. 支持代理服务器等
  3. OKhttp3
    1. OKHttp是一个当前主流的网络请求的开源框架, 用于替代HttpUrlConnection和Apache HttpClient
    2. 支持http2.0,对一台机器的请求共享一个socket。
    3. 采用连接池技术,可以有效的减少Http连接数量。
    4. 无缝集成GZIP压缩技术。
    5. 支持Response Cache,避免重复请求
    6. 域名多IP支持
  4. RestTemplate

    1. Spring RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率,所以很多客户端比如 Android或者第三方服务商都是使用 RestTemplate 请求 restful 服务。
    2. 面向 URL 组件,必须依赖于主机 + 端口 + URI
    3. RestTemplate 不依赖于服务接口,仅关注 REST 响应内容
    4. Spring Cloud Feign

      5.2.2 RPC 框架

      RPC全称为remote procedure call,即远程过程调用。借助RPC可以做到像本地调用一样调用远程服务,是一种进程间的通信方式. 。常见的RPC框架有一下几种.
  5. Java RMI

    1. Java RMI(Romote Method Invocation)是一种基于Java的远程方法调用技术,是Java特有的一种RPC实现。
    2. image.png
  6. Hessian
    1. Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。
    2. image.png
  7. Dubbo
    1. Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成。Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
    2. image.png
  8. gRPC
    1. gRPC是由Google公司开源的一款高性能的远程过程调用(RPC)框架,可以在任何环境下运行。该框架提供了负载均衡,跟踪,智能监控,身份验证等功能,可以实现系统间的高效连接。
    2. image.png

      5.3 跨域调用

      5.3.1 跨域

      在分布式系统中, 会有调用其他业务系统,导致出现跨域问题,跨域实质上是浏览器的一种保护处理。如果产生了跨域,服务器在返回结果时就会被浏览器拦截(注意:此时请求是可以正常发起的,只是浏览器对其进行了拦截),导致响应的内容不可用. 产生跨域的几种情况有一下:
当前页面URL 被请求页面URL 跨域 原因
http://www.lagou.com/ http://www.lagou.com/index.html 同源(协议, 域名, 端口号相同)
http://www.lagou.com/ https://www.lagou.com/index.html 协议不同(http/https)
http://www.lagou.com/ http://www.baidu.com/ 主域名不同(lagou/baidu)
http://www.lagou.com/ http://kaiwu.lagou.com/ 子域名不同(www/kaiwu)
http://www.lagou.com:8080 http://www.lagou.com:8090 端口号不同(8080/8090)

5.3.2 常见的解决方案

  1. 使用jsonp解决网站跨域
    1. 缺点:不支持post请求,代码书写比较复杂
  2. 使用HttpClient内部转发
  3. 使用设置响应头允许跨域
    1. response.setHeader(“Access-Control-Allow-Origin”, “*”); 设置响应头允许跨域.
  4. 基于Nginx搭建企业级API接口网关
  5. 使用Zuul搭建微服务API接口网关
    1. Zuul是spring cloud中的微服务网关。网关: 是一个网络整体系统中的前置门户入口。请求首先通过网关,进行路径的路由,定位到具体的服务节点上。可以使用zuul的过滤器的请求转发去解决跨域问题