1 远程过程调用流程

微服务RESTful API互相调用_服务器

2 HttpClient介绍

HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。现在HttpClient最新版本为 HttpClient 4.5 .6(2015-09-11)

2.1 HttpClient入门案例

2.1.1 添加jar包
<!--添加httpClient jar包 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
2.1.2 编辑入门案例
public class TestHttpClient {

    /**
     * 1.实例化HttpClient客户端对象
     * 2.定义url地址
     * 3.定义请求类型
     * 4.发起httpClient请求
     * 5.获取响应结果 分析状态码信息  200 404 500 504 502
     * 6.获取结果,进行后续操作
     */
    @Test
    public void testGet() throws IOException {
        HttpClient httpClient = HttpClients.createDefault();
        String url = "http://www.baidu.com";
        HttpGet httpGet = new HttpGet(url);
        HttpResponse httpResponse = httpClient.execute(httpGet);
        if(httpResponse.getStatusLine().getStatusCode() == 200){
            //表示请求一切正常
            HttpEntity httpEntity = httpResponse.getEntity();//获取响应结果实体对象
            String result  = EntityUtils.toString(httpEntity, "UTF-8");
            System.out.println(result);
        }else{
            //表示请求有误
            System.out.println("请求结果有误!!!");
        }
    }
}

2.2 HttpClient案例说明

2.2.1 业务场景

要求:
1)通过http://www.jt.com/user/findUserList,并且要求JSON结构返回用户数据…
2)JT-WEB服务器网址应该向JT-SSO获取用户信息.
URL: http://sso.jt.com/userfindUserList. 获取全部的用户信息.
使用HttpClient方式实现.

2.2.2 编辑JT-SSO UserController
/**
     * 完成HttpClient业务调用
     * url地址: http://sso.jt.com/user/findUserList
     * 返回值: UserJSON
     */
    @RequestMapping("/findUserList")
    public List<User> findUserList(){

        return userService.findUserList();
    }
2.2.3 编辑JT-SSO UserService
@Override
    public List<User> findUserList() {
        return userMapper.selectList(null);
    }
2.2.4 编辑JT-WEB UserController
/**
     * 完成HttpClient测试
     * 1.url地址: http://www.jt.com/user/findUserList
     * 2.请求参数: 无
     * 3.返回值结果: List<User>集合
     */
    @RequestMapping("/findUserList")
    @ResponseBody
    public List<User> findUserList(){

        return httpClientService.findUserList();
    }
2.2.5 编辑JT-WEB HttpClientUserServiceImpl
@Service
public class HttpClientUserServiceImpl implements HttpClientService{

    //jt-web 需要访问jt-sso获取数据  HttpClient
    //http://sso.jt.com/userfindUserList
    @Override
    public List<User> findUserList() {
        List<User> userList = new ArrayList<>();
        String url = "http://sso.jt.com/user/findUserList";
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse httpResponse = httpClient.execute(httpGet);
            if(httpResponse.getStatusLine().getStatusCode() == 200){
                String json =
                        EntityUtils.toString(httpResponse.getEntity(),"UTF-8");
                userList = ObjectMapperUtil.toObject(json, userList.getClass());
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        return userList;
    }
}

3.微服务思想

3.1 SOA思想

面向服务的架构(SOA)是一个组件模型(编程方法),它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协议联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。

微服务RESTful API互相调用_List_02

3.2 RPC(规则)

RPC是远程过程调用(Remote Procedure Call)的缩写形式。SAP系统RPC调用的原理其实很简单,有一些类似于三层构架的C/S系统,第三方的客户程序通过接口调用SAP内部的标准或自定义函数,获得函数返回的数据进行处理后显示或打印。

本地过程调用: 如果需要完成业务逻辑,则直接去调用本地的方法即可.
远程过程调用: 我想完成一个业务的调用,但是该功能我没有办法直接调用,需要通过第三方帮助我完成业务规则.
具体用法: RPC不关注具体的实现规则,用户也不需要了解具体的协议.谁调用谁实现.

3.3 Http协议规范

微服务RESTful API互相调用_List_03

4.微服务调用思想

4.1 传统方式调用问题说明

微服务RESTful API互相调用_List_04

4.2 微服务思想-注册中心

微服务: 架构设计采用分布式思想,当服务器发生故障时,可以实现自动化的故障迁移.无需人为干预.

微服务RESTful API互相调用_客户端_05


注册中心实现原理:

1.当服务器启动时,会将服务器的状态(服务名称/IP/端口) 一起写入注册中心

2.注册中心接收到服务器信息时,会动态的维护服务列表数据.

3/4.当客户端(消费者)启动时,首先会链接注册中心,获取所有的服务列表数据.并且将服务列表数据保存到本地.

5.当消费者执行业务调用时,如果有多个服务的生产者时,采用负载均衡的思想挑选其中的一个服务进行访问(RPC).

6.当服务器发生宕机时,由于注册中心有心跳检测机制,所有会动态的维护服务列表数据.会全网广播通知所有的客户端(消费者)更新服务列表数据. 在更新服务列表时,数据的同步会陷入阻塞的状态.

4.3 关于微服务思想负载均衡说明

4.3.1 集中式负载均衡

说明: 所有的请求都必须由某个服务器进行统一的管理.
案例: Nginx是集中式的负载均衡,但是nginx主要的作用是做反向代理

4.3.2 客户端负载均衡

说明: 请求发送之前,每个客户端都非常清楚的知道,自己应该访问哪台服务器.
在服务器内部.由客户端直接访问后端服务器,将负载的压力进行了分担.

5. 注册中心-zookeeper安装

说明: 具体的安装方式参考资料文档.

微服务RESTful API互相调用_List_06

5.1. zk启动命令

微服务RESTful API互相调用_服务器_07

5.2 关于集群相关概念

5.2.1 几台服务器可以搭建集群

公式: 存活节点 > N/2
算数计算:
1个节点 1-1 > 1/2 假的 不能搭建集群
2个节点 2-1 > 2/2 假的 不能搭建集群
3个节点 3-1 > 3/2 真的 可以搭建集群
结论:集群最小单位3台.

5.2.2 集群一般都是奇数台为什么?

3个节点 3-1 > 3/2 真的 可以搭建集群 允许宕机1台
4个节点 4-1 > 4/2 真的 可以搭建集群 允许宕机1台
说明: 由于搭建偶数台和搭建奇数台的容灾效果相同的,所以一般都是奇数个.

5.2.3 集群中的脑裂现象?

说明: 由于集群工作过程中主机意外宕机. 之后集群开始进行选举.如果出现多次连续平票状态时,则可能出现脑裂现象.

脑裂发生的概率是: 1/8=12.5%

如何有效降低脑裂现象发生: 增加节点的数量

微服务RESTful API互相调用_客户端_08

5.3 关于zk集群搭建问题说明

1).如何检查报错

微服务RESTful API互相调用_客户端_09


2). 检查myid位置及值

微服务RESTful API互相调用_List_10


3).检查集群配置

微服务RESTful API互相调用_微服务RESTful API互相调用_11

5.4 关于zk集群选举的规范

说明: zk集群选举规则是myid最大值优先的算法,如果选举结束,则剩余的节点当新主机的从机.

考题1: 如果依次启动1-7台zk节点

问1: 谁当主机? 4

问2: 谁永远不能当选主机? 1,2,3

微服务RESTful API互相调用_微服务RESTful API互相调用_12

5.5 ZK工作原理说明

Zookeeper集群中leader负责监控集群状态同步数据,follower主要负责客户端链接获取服务列表信息.同时参与投票.

6. Dubbo框架

6.1 Dubbo框架介绍

Apache Dubbo |ˈdʌbəʊ| 提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维。

6.2 Dubbo入门案例

6.2.1 导入jar包
<!--引入dubbo配置 如果下载失败 则去本地仓库中删除重新下载-->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>
6.2.2 导入项目

1).修改版本号 因为导入的项目springboot版本低

微服务RESTful API互相调用_微服务RESTful API互相调用_13


2).修改子项目名称 手误写错了

微服务RESTful API互相调用_微服务RESTful API互相调用_14


3).复制项目

微服务RESTful API互相调用_服务器_15


4).添加为maven项目

微服务RESTful API互相调用_微服务RESTful API互相调用_16

6.3 关于入门案例说明

6.3.1 定义中立接口

1).项目结构

微服务RESTful API互相调用_微服务RESTful API互相调用_17


2).定义接口

微服务RESTful API互相调用_List_18

6.3.2 编辑服务生产者
6.3.2.1 编辑接口实现

说明:注意注解导入的是dubbo的注解

微服务RESTful API互相调用_客户端_19

6.3.2.2 编辑YML配置文件
server:
  port: 9000   #定义tomcat端口  服务启动时占用的端口

spring:
  datasource:
    #引入druid数据源
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root

#关于Dubbo配置   
dubbo:
  scan:
    basePackages: com.jt    #指定dubbo的包路径
  application:              #应用名称
    name: provider-user     #一个接口对应一个服务名称 如果是多个实现类则应用名称一致
  registry:
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
  protocol:  #指定协议
    name: dubbo  #使用dubbo协议(tcp-ip)  web-controller直接调用sso-Service
    port: 20880  #每一个服务都有自己特定的端口 不能重复.

      
mybatis-plus:
  type-aliases-package: com.jt.dubbo.pojo       #配置别名包路径
  mapper-locations: classpath:/mybatis/mappers/*.xml  #添加mapper映射文件
  configuration:
    map-underscore-to-camel-case: true                #开启驼峰映射规则
6.3.2.3 生产者启动测试

微服务RESTful API互相调用_List_20


微服务RESTful API互相调用_客户端_21

6.3.3 编辑服务消费者
6.3.3.1 编辑UserController

微服务RESTful API互相调用_微服务RESTful API互相调用_22

6.3.3.2 编辑消费者的YML配置文件
server:
  port: 8092    
spring:     #定义springmvc视图解析器
  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp

dubbo:
  scan:
    basePackages: com.jt
  application:
    name: consumer-user   #定义消费者名称
  registry:               #注册中心地址
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183