高并发Day16--Dubbo&Zookeeper

Posted MyMethod

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高并发Day16--Dubbo&Zookeeper相关的知识,希望对你有一定的参考价值。


1 Dubbo介绍
高并发Day16--Dubbo&Zookeeper



1.1 官网介绍

http://dubbo.apache.org/zh-cn/

高并发Day16--Dubbo&Zookeeper

1.2 Dubbo框架介绍

Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

1.3 调用过程

高并发Day16--Dubbo&Zookeeper

1.4 微服务框架定义

程序在分布式的基础之上,让程序分而治之.如果出现了问题,也能自动的实现故障的迁移.无需人为操作.

1.5 SOA思想

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


高并发Day16--Dubbo&Zookeeper



微服务程序编码的一种实际方案.

1.6 RPC(概念)

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

定义:分布式系统中系统之间的通信的方式称之为RPC,远程过程调用

无需关注通信具体协议细节.可以利用RPC工具直接获取远程服务器数据.



高并发Day16--Dubbo&Zookeeper
2 Zookeeper
高并发Day16--Dubbo&Zookeeper



2.1 Zookeeper介绍

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

ZooKeeper包含一个简单的原语集,提供Java和C的接口。

ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在zookeeper-3.4.3src ecipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。

2.2.1 Zookeeper下载

网址: http://zookeeper.apache.org/releases.html.

如图-2所示

高并发Day16--Dubbo&Zookeeper

图-2

下载路径,点击download.

如图-3所示

高并发Day16--Dubbo&Zookeeper

图-3

http://mirrors.hust.edu.cn/apache/zookeeper/

如图-4所示

高并发Day16--Dubbo&Zookeeper

图-4

2.2.2 Zookeeper安装

2.2.2.1 安装JDK

将JDK1.8文件上传到Linux操作系统中/src/usr/local/java/文件下.

如图-5所示

高并发Day16--Dubbo&Zookeeper

图-5

1.解压文件

tar -xvf jdk-8u51-linux-x64.tar.gz

2.配置环境变量

编辑环境变量配置文件

vim /etc/profile

如图-6所示

高并发Day16--Dubbo&Zookeeper

图-6

使JDK生效,之后检查jdk安装是否成功

source /etc/profile

如图 -7所示

高并发Day16--Dubbo&Zookeeper

图-7

2.2.2.2 上传安装文件

说明:上传zookeeper安装文件.之后解压.

如图-8所示

高并发Day16--Dubbo&Zookeeper

图-8

解压目录:

tar -xvf zookeeper-3.4.8.tar.gz

2.2.2.3 修改配置文件

在zk根目录下创建文件夹data/log

mkdir data log

如图-9所示

高并发Day16--Dubbo&Zookeeper

图-9

复制配置文件并且修改名称

cp zoo_sample.cfg zoo.cfg

如图-10所示

高并发Day16--Dubbo&Zookeeper

图-10

2.2.2.4 启动zk

zk启动关闭命令如下.

sh zkServer.sh start 或者 ./zkServer.sh startsh zkServer.sh stopsh zkServer.sh status

如图-11所示

高并发Day16--Dubbo&Zookeeper

图-11


高并发Day16--Dubbo&Zookeeper
3 Zookeeper集群安装
高并发Day16--Dubbo&Zookeeper



3.1 集群划分规定

规则: 集群剩余节点的数量 > n/2;

例子:

1-1 > 1/2   错误      1台不能搭建集群
2-1   > 2/2   错误      2台不能搭建集群
3-1   > 3/2   可以   3台可以搭建集群 3台搭建集群最小单位
4-1   > 4/2    可以
4-2   > 4/2    不可以

面试题:

为什么集群是单数台?  原因:偶数太和奇数台容灾效果相同,所以没有必要搭建偶数台.

面试题2:

集群选举中如果出现平票会发生什么?  如何预防?

如果连续3次平票,则可能出现脑裂现象. 1/8.

可以通过增加集群节点的数量来有效的降低脑裂的发生概率.

3.2 准备文件夹

在zookeeper根目录中创建新的文件夹zkCluster.

如图-12所示

高并发Day16--Dubbo&Zookeeper

图-12

如图-13所示

创建zk1/zk2/zk3文件夹.

高并发Day16--Dubbo&Zookeeper

图-13

在每个文件夹里创建data/log文件夹.

mkdir {zk1,zk2,zk3}/{data,log}

如图-14所示

高并发Day16--Dubbo&Zookeeper

图-14

3.3 添加myid文件

分别在zk1/zk2/zk3中的data文件夹中创建新的文件myid.其中的内容依次为1/2/3,与zk节点号对应.

如图-15所示

高并发Day16--Dubbo&Zookeeper

图-15

编辑myid文件,定义编号.

如图-16所示

高并发Day16--Dubbo&Zookeeper

图-16

3.4 编辑配置文件

将zoo_sample.cfg 复制为zoo1.cfg之后修改配置文件.

如图-17所示

高并发Day16--Dubbo&Zookeeper

图-17

3.5 修改zoo1.cfg

如图-18所示

高并发Day16--Dubbo&Zookeeper

图-18

配置完成后将zoo1.cfg复制2份.之后需要修改对应的文件夹目录.和不同的端口即可.

3.6 ZK集群测试

通过下面的命令启动zk集群.

sh zkServer.sh start zoo1.cfgsh zkServer.sh stop zoo1.cfgsh zkServer.sh status zoo1.cfg

检查主从关系,从机情况说明.

如图-19所示

高并发Day16--Dubbo&Zookeeper

图-19

检查主从关系,主机情况说明.

如图-20所示

高并发Day16--Dubbo&Zookeeper

图-20

3.7 关于zookeeper集群说明

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

图-30


高并发Day16--Dubbo&Zookeeper
4 Dubbo调用原理
高并发Day16--Dubbo&Zookeeper



4.1 原理说明

需求:能否实现服务的自动发现和注册.

高并发Day16--Dubbo&Zookeeper

1. 当服务提供者启动时,会将服务数据保存到zk中.
2. 当zk接收用户服务信息之后,会将数据保存到服务列表中.
3. 当消费者启动时,先连接zk获取zk的服务列表,
4. 之后缓存到本地,方便下次访问.
5. 消费者接收用户的请求时,根据负载均衡策略 实现请求的发送.并且获取服务端的数据(RPC)
6. Zk实时的心跳检测,如果后台服务器宕机,则需要更新自己的服务列表.同时广播给全部的客户端.


高并发Day16--Dubbo&Zookeeper
5 Dubbo入门案例
高并发Day16--Dubbo&Zookeeper



5.1 项目搭建

1. 构建接口项目 jar包
2. 构建服务的提供者  jar包    依赖接口  实现接口
3. 构建服务的消费者 jar/war 依赖接口  调用接口

5.2 导入项目步骤

1. 说明将课前资料中的dubbo的入门案例 导入本地工作空间中.

高并发Day16--Dubbo&Zookeeper


2.导入dubbo项目

高并发Day16--Dubbo&Zookeeper

5.3 定义公共API接口

高并发Day16--Dubbo&Zookeeper

5.4 添加依赖包

<!--引入dubbo配置 --><dependency><groupId>com.alibaba.boot</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>0.2.0</version></dependency>

5.5 定义服务提供者


5.5.1 编辑POM.xml文件

<parent><groupId>com.jt.dubbo</groupId><artifactId>dubbo-jt</artifactId><version>0.0.1-SNAPSHOT</version></parent><artifactId>dubbo-jt-demo-provider</artifactId><dependencies> <dependency> <groupId>com.jt.dubbo</groupId> <artifactId>dubbo-jt-demo-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency></dependencies>

5.5.2 编辑Service具体实现

@Service(timeout=3000) //3秒超时public class UserServiceImpl implements UserService {
@Autowiredprivate UserMapper userMapper;@Overridepublic List<User> findAll() {
System.out.println("我是第一个服务的提供者");return userMapper.selectList(null);}
@Overridepublic void saveUser(User user) {
userMapper.insert(user);}

}

5.5.3 修改YML配置文件

server:port: 9000

spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=trueusername: rootpassword: root

dubbo:scan: #包扫描basePackages: com.jtapplication:name: provider-userregistry: #注册中心address: zookeeper://192.168.226.128:2181?backup=192.168.226.128:2182,192.168.226.128:2183protocol: #协议name: dubbo #dubbo协议 TCP/IPport: 20880 #服务唯一端口号信息



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



5.6 定义服务消费者

5.6.1 添加依赖项

<parent><groupId>com.jt.dubbo</groupId><artifactId>dubbo-jt</artifactId><version>0.0.1-SNAPSHOT</version></parent><artifactId>dubbo-jt-demo-consumer</artifactId><dependencies> <dependency> <groupId>com.jt.dubbo</groupId> <artifactId>dubbo-jt-demo-interface</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency></dependencies>

5.6.2 编辑消费者的Controller

@RestControllerpublic class UserController {
/*** check:是否校验提供者*/@Reference(timeout=3000,check=true)private UserService userService;//第三方的接口
/*** RPC表示远程过程调用,调用者使用RPC就相当于使用自己的服务* RPC程序引入rpc时使用代理模式,* 要求调用代理和调用真实的服务没有区别.* @return*/@RequestMapping("/findAll")public List<User> findAll(){
return userService.findAll();}
@RequestMapping("/saveUser/{name}/{age}/{sex}")public String saveUser(User user) {
userService.saveUser(user);return "用户入库成功!!!";}}

5.6.3 编辑消费者YML配置文件

server:port: 9001dubbo:scan:basePackages: com.jtapplication:name: consumer-userregistry:address: zookeeper://192.168.226.128:2181?backup=192.168.226.128:2182,192.168.226.128:2183

5.7 页面调用效果

高并发Day16--Dubbo&Zookeeper

5.8 Dubbo框架报错异常

报错异常: type user 不能转化为  type user

高并发Day16--Dubbo&Zookeeper

原因:由于springBoot的热部署导致.

解决: 重启提供者和消费者


高并发Day16--Dubbo&Zookeeper
6 Dubbo框架特性
高并发Day16--Dubbo&Zookeeper



6.1 负载均衡测试

测试说明:根据一个消费者有多个提供者的状态的配置,发现确实可以实现负载均衡.

6.2 Dubbo负载均衡策略

默认策略: 随机访问.

1.随机策略   RandomLoadBalance
@Reference(timeout=3000,check=true,loadbalance = "random")private UserService userService;//第三方的接口
2. 轮询策略  RoundRobinLoadBalance
@Reference(timeout=3000,check=true,loadbalance ="roundrobin")
3.Iphash策略   ConsistentHashLoadBalance
/*** check:是否校验提供者* loadbalance="负载均衡的配置"*/@Reference(timeout=3000,check=true,loadbalance ="consistenthash")private UserService userService;//第三方的接口
4. 最小活跃数     LeastActiveLoadBalance

挑选连接数较小的访问.

@Reference(timeout=3000,check=true,loadbalance ="leastactive")private UserService userService;//第三方的接口

6.3 面试题

1.Zookeeper服务器宕机,dubbo框架是否可以正常工作.

答案: 依然可以访问,由于消费者启动时已经将服务信息缓存到本地.


2.如果后台有一个提供者宕机,问用户访问是否报错?

答案: 不会报错,用户依然可以正常访问.原因本地服务列表也会动态更新.

这时这个程序处于高危运行状态


高并发Day16--Dubbo&Zookeeper
7 京淘 Dubbo框架重构
高并发Day16--Dubbo&Zookeeper



7.1 重构说明

1. jt-common 是dubbo框架的接口
2. jt-web    是dubbo框架的消费者
3. jt-sso    是dubbo框架的提供者

7.2 引入jar包

<!--引入dubbo配置 --><dependency><groupId>com.alibaba.boot</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>0.2.0</version></dependency>

7.3 定义公共的API接口

//定义公共的API接口public interface DubboUserService {

}

7.4 定义jt-sso的提供者

7.4.1 编辑YML配置

server:port: 8093servlet:context-path: /spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=trueusername: rootpassword: root

#mybatis-plush配置mybatis-plus:type-aliases-package: com.jt.pojomapper-locations: classpath:/mybatis/mappers/*.xmlconfiguration:map-underscore-to-camel-case: true#引入日志信息logging:level:com.jt.mapper: debug

dubbo:scan: #包扫描basePackages: com.jtapplication:name: provider-userregistry: #注册中心address: zookeeper://192.168.226.128:2181?backup=192.168.226.128:2182,192.168.226.128:2183protocol: #协议name: dubbo #dubbo协议 TCP/IPport: 20880 #服务唯一端口号信息

7.4.2 创建Dubbo的UserService实现类

@Service //dubbo注解public class DubboUserServiceImpl implements DubboUserService {
@Autowiredprivate UserMapper userMapper;

}

7.5  服务消费者改造

7.5.1 编辑jt-web的YML配置文件

server:port: 8092spring: #定义springmvc视图解析器mvc:view:prefix: /WEB-INF/views/suffix: .jsp

dubbo:scan:basePackages: com.jtapplication:name: consumer-webregistry:address: zookeeper://192.168.226.128:2181?backup=192.168.226.128:2182,192.168.226.128:2183

7.5.2 编辑UserController

说明:注入中立第三方接口.

高并发Day16--Dubbo&Zookeeper



高并发Day16--Dubbo&Zookeeper
8 用户注册
高并发Day16--Dubbo&Zookeeper



8.1 需求说明

当用户通过form表单提交参数时,将数据首先通过jt-web服务器传递参数.之后发起RPC调用jt-sso服务器.实现用户的注册.

8.2 页面分析

1. 页面url地址

高并发Day16--Dubbo&Zookeeper


2. 查看页面JS

检查页面JS,确定返回值数据. 返回值结果SysResult对象

$.ajax({type : "POST",url : "/user/doRegister",contentType : "application/x-www-form-urlencoded; charset=utf-8",data : {password:_password,username:_username,phone:_phone},dataType : 'json',success : function(result) {if(result.status == "200"){// 注册成功,去登录页showMessage('注册成功,请登录!');verc();$("#registsubmit").removeAttr("disabled").removeClass().addClass("btn-img btn-regist");isSubmit = false;return;}else{showMessage('注册失败,请联系管理员!');//alert('注册失败,请重新注册! ' + result.data );}

8.3 编辑UserController

/*** password: admin123username: admin1909phone: 13212313121* @return*/@RequestMapping("/doRegister")@ResponseBody //转化JSONpublic SysResult saveUser(User user) {
userService.saveUser(user);//RPC调用return SysResult.success();}

8.4 编辑UserService

@Service //dubbo注解public class DubboUserServiceImpl implements DubboUserService {
@Autowiredprivate UserMapper userMapper;

/*** 1.密码明文 需要加密 md5/md5Hash* 2.需要添加创建/更新时间* 3.暂时使用phone代替email email为非null*/@Overridepublic void saveUser(User user) {String password = user.getPassword();String md5Pass = DigestUtils.md5DigestAsHex(password.getBytes());user.setPassword(md5Pass).setEmail(user.getPhone()).setCreated(new Date()).setUpdated(user.getCreated());
userMapper.insert(user);}
}

8.5 页面效果



扫描二维码

获取更多收获

MyMethod




以上是关于高并发Day16--Dubbo&Zookeeper的主要内容,如果未能解决你的问题,请参考以下文章

Day434.订单&库存服务分布式事务的最终解决 -谷粒商城

Day434.订单&库存服务分布式事务的最终解决 -谷粒商城

Day298.并发容器&并发队列 -Juc

高并发Day09--Linux tomcat集群搭建

Day810.MySQL调优之事务:高并发场景下的数据库事务调优 -Java 性能调优实战

构建高并发&高可用&安全的IT系统-高并发部分