JAVA分布式篇3——Dubbo
JAVA分布式篇3——Dubbo
1、架构演变
1.1、单应用架构
- 当网站流量很小时,只需要一个应用,将所有的功能部署到一起(所有业务都放在一个tomcat 里),从而减少部署节点和成本
- 用于简化 增删改查 工作量的数据访问框架 (ORM)是关键
- 例如:某个超市的收银系统,某个公司的员工管理系统
优点
- 小项目开发快
- 成本低
- 架构简单
- 易于测试
- 易于部署
缺点
- 大项目模块耦合严重
- 不易开发,维护
- 沟通成本高
- 新增业务困难
- 核心业务与边缘业务混合在一块,出现问题互相影响
1.2、垂直应用架构
- 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成几个互不相干的几个应 用,以提高效率
- 大模块按照mvc分层模式,进行拆分成多个互不相关的小模块,并且每个小模块都有独立的服务器
- 用于加速前端页面开发的web框架(MVC)是关键;因为每个小应用都有独立的页面
缺点
- 模块之间不可能完全没有交集,公用模块无法重复利用,开发性的浪费
1.3、分布式服务架构
- 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的业务,逐渐形成 稳健的服务中心,使前端应用能更快速的响应多变的市场需求
- 此时,用户提高业务复用及整合的分布式服务框架(RPC)远程调用是关键
1.4、流动计算架构
- 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐呈现,此时需增加一个调度中心基于 访问压力实时管理集群容量,提高集群利用率
- 此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键
2、Dubbo
- Dubbo是分布式服务框架,是阿里巴巴的开源项目,现交给apache进行维护
- Dubbo致力于提高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案
3、RPC
RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式
3.1、RPC通信原理
- 在客户端将对象进行序列化
- 底层通信框架使用netty(基于tcp协议的socket),将序列化的对象发给服务方提供方
- 服务提供方通过socket得到数据文件之后,进行反序列化,获得要操作的对象
- 对象数据操作完毕,将新的对象序列化,再通过服务提供方的socket返回给客户端
- 客户端获得序列化数据,再反序列化,得到最新的数据对象,至此,完成一次请求
RPC的核心:通信、序列化
4、Dubbo角色介绍
节点 | 角色说明 |
---|---|
Provider | 服务的提供方 |
Consumer | 服务的消费方 |
Registry | 服务注册与发现的注册中心 |
Monitor | 监控服务的统计中心 |
Container | 服务运行容器 |
4.1、启动流程
- 服务容器负责启动,加载,运行服务提供者
- 服务提供者在启动时,向注册中心注册自己提供的服务
- 服务消费者在启动时,向注册中心订阅自己所需的服务
- 在注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给 消费者
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
5、Dubbo快速入门
5.1、dubbo监控
在正式开始dubbo前,我们先来处理dubbo监控问题
github https://github.com/apache/dubbo-admin
官网打不开可尝试下面地址
gitee https://codechina.csdn.net/mirrors/apache/dubbo-admin
百度云:https://pan.baidu.com/s/1_b6X3SkgTskLdal3HTtHmw提取码:exa0
进入dubbo-admin-master
如zookeeper与dubbo不在一台机器,需修改配置文件(dubbo-admin-master\dubbo-admin\src\main\resources\application.properties)
打开cmd,执行mvn package -Dmaven.skip.test=true,时间会有点久,出现下图表成功
进入dubbo-admin-master\dubbo-admin\target,拷贝jar包到服务器,后台启动jar包
[root@VM-8-13-centos bin]# cd /root
[root@VM-8-13-centos ~]# ls
dubbo-admin-0.0.1-SNAPSHOT.jar
[root@VM-8-13-centos ~]# nohup java -jar dubbo-admin-0.0.1-SNAPSHOT.jar > dubbo-admin.log 2>&1 &
[1] 32315
[root@VM-8-13-centos ~]# netstat -tunlp|grep 7001
tcp6 0 0 :::7001 :::* LISTEN 32315/java
访问监控页面
http://81.70.1.65:7001/
默认账号密码都为root
到此监控页面配置完成
下面介绍linux结束进程
首先查看端口pid
[root@VM-8-13-centos ~]# netstat -tunlp|grep 7001
tcp6 0 0 :::7001 :::* LISTEN 32315/java
杀死进程
[root@VM-8-13-centos ~]# kill -9 32315
5.2、创建maven项目导入依赖
5.2.1、服务方
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://xmlns.jcp.org/xml/ns/javaee"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"id="WebApp_ID" version="3.1"><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContent.xml</param-value></context-param>
</web-app>
log4j.properties
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/zk.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
applicationContext.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!--应用别名--><dubbo:application name="winkto-dubbo-provider"/><!--注册中心地址--><dubbo:registry address="zookeeper://81.70.1.65:2181" timeout="30000"/><!--服务--><dubbo:annotation package="cn.winkto.service" />
</beans>
服务
public interface RuoyeService {public String sayBye(String name);
}
@DubboService
public class RuoyeServiceImpl implements RuoyeService {public String sayBye(String name) {System.out.println(name);return name+" bye";}
}
5.2.2、消费方
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--注册DispatcherServlet--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-config.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><!--/ 匹配所有的请求;(不包括.jsp)--><!--/* 匹配所有的请求;(包括.jsp)--><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>
log4j.properties
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/zk.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
springmvc-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttps://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://dubbo.apache.org/schema/dubbohttp://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!--Dubbo的应用名称,通常使用项目名 --><dubbo:application name="dubbo-consumer" /><!--配置Dubbo的注册中心地址 --><dubbo:registry address="zookeeper://81.70.1.65:2181" timeout="30000" /><dubbo:annotation package="cn.winkto.controller" /><!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 --><context:component-scan base-package="cn.winkto.controller"/><!-- 让Spring MVC不处理静态资源 --><mvc:default-servlet-handler /><!--处理器映射器和处理器适配器,以及功能增强--><mvc:annotation-driven /></beans>
伪服务接口
public interface RuoyeService {public String sayBye(String name);
}
controller
@RestController
public class YoyaController {@DubboReferenceprivate RuoyeService ruoyeService;@RequestMapping("/bye/{name}")public String bye(@PathVariable String name){System.out.println(name);return ruoyeService.sayBye(name);}
}
测试
http://localhost:8082/dubbo_consumer_war_exploded/bye/yoya
6、配置详解
6.1、启动检查
启动时会在注册中心检查依赖的服务是否可用,不可用时会抛出异常
<!--默认是true:抛异常;false:不抛异常-->
<dubbo:consumer check="false" />
6.2、超时时间
由于网络或服务端不可靠,会导致调用过程中出现不确定的阻塞状态(超时) 为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间
<!--设置超时时间为2秒,默认为1秒-->
<dubbo:provider timeout="2000"/>
dubbo推荐在Provider上尽量多配置Consumer端属性
- 作服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试 次数,等等
- 在Provider配置后,Consumer不配置则会使用Provider的配置值,即Provider配置可 以作消费者的缺省值
6.3、重试次数
当出现失败,自动切换并重试其它服务器,dubbo重试的缺省值是2次,我们可以自行设置(在提供方设置)
<dubbo:provider timeout="2000" retries="3"/>
并不是所有的方法都适合设置重试次数
- 幂等方法:适合(当参数一样,无论执行多少次,结果是一样的,例如:查询,修改)
- 非幂等方法:不适合(当参数一样,执行结果不一样,例如:删除,添加)
配置重试次数
<dubbo:reference id="ruoyeService" interface="cn.winkto.service.RuoyeService"><dubbo:method name="bye" retries="1"/>
</dubbo:reference>
6.4、多版本配置
提供者
@DubboService
public class RuoyeServiceImpl1 implements RuoyeService {public String sayBye(String name) {System.out.println(name);return name+" bye";}
}
@DubboService
public class RuoyeServiceImpl2 implements RuoyeService {public String sayBye(String name) {System.out.println(name);return name+" byebye~";}
}
<dubbo:service interface="cn.winkto.service.RuoyeService" class="cn.winkto.service.RuoyeServiceImpl1" version="1.0.0"/>
<dubbo:service interface="cn.winkto.service.RuoyeService" class="cn.winkto.service.RuoyeServiceImpl2" version="2.0.0"/>
消费者
<dubbo:reference id="ruoyeService" interface="cn.winkto.service.RuoyeService" version="2.0.0"><dubbo:method name="bye" retries="1"/>
</dubbo:reference>
@RestController
public class YoyaController {@DubboReference(version = "2.0.0")private RuoyeService ruoyeService;@RequestMapping("/bye/{name}")public String bye(@PathVariable String name){System.out.println(name);return ruoyeService.sayBye(name);}
}
消费者的控制层要改为自动注入
当消费者的版本修改为 version="*",那么就会随机调用服务提供者的版本
6.5、本地存根
先在消费者处理一些业务逻辑,再调用提供者的过程,就是“本地存根”
在消费者,创建一个接口实现类,注意:必须使用构造方法的方式注入
@Service
public class RuoyeServiceImpl implements RuoyeService {private RuoyeService ruoyeService;public RuoyeServiceImpl(RuoyeService ruoyeService) {this.ruoyeService = ruoyeService;}public String sayBye(String name) {if (!name.equals("zhangsan"))return ruoyeService.sayBye(name);return "名称不正确哦";}
}
@RestController
public class YoyaController {@DubboReference(version = "2.0.0",stub = "cn.winkto.service.RuoyeServiceImpl")private RuoyeService ruoyeService;@RequestMapping("/bye/{name}")public String bye(@PathVariable String name){System.out.println(name);return ruoyeService.sayBye(name);}
}
6.6、负载均衡策略
- 负载均衡(Load Balance), 其实就是将请求分摊到多个操作单元上进行执行,从而共同完成工作 任务
- dubbo一共提供4种策略,缺省为 random 随机分配调用
6.7、高可用
zookeeper注册中心宕机,还可以消费dubbo暴露的服务
- 监控中心宕掉不影响使用,只是丢失部分采样数据
- 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
- 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
- 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯 服务提供者无状态,任意一台宕掉后,不影响使用
- 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
6.8、 服务降级
服务降级,就是根据实际的情况和流量,对一些服务有策略的停止或换种简单的方式处理,从而释 放服务器的资源来保证核心业务的正常运行
- 在 管理控制台配置服务降级:屏蔽和容错
- 屏蔽:mock=force:return+null 表示消费方对该服务的方法调用都 直接返回 null 值,不发起远程 调用。用来屏蔽不重要服务不可用时对调用方的影响
- 容错:mock=fail:return+null 表示消费方对该服务的方法调用在 失败后,再返回 null 值,不抛异 常。用来容忍不重要服务不稳定时对调用方的影响
JAVA分布式篇3——Dubbo相关推荐
- Java分布式篇6——RabbitMQ
Java分布式篇6--RabbitMQ 1.MQ(Message Queue)消息队列 消息队列中间件,是分布式系统中的重要组件 主要解决,异步处理,应用解耦,流量削峰等问题 实现高性能,高可用,可伸 ...
- Java分布式篇5——FastDFS
Java分布式篇5--FastDFS 分布式文件系统 1.主流的分布式文件系统 1.1. HDFS (Hadoop Distributed File System)Hadoop 分布式文件系统 高容错 ...
- Java分布式篇4——Redis
Java分布式篇4--Redis 1.互联网架构的演变历程 1.1.第一阶段 数据访问量不大,简单的架构即可搞定! 1.2.第二阶段 数据访问量大,使用缓存技术来缓解数据库的压力 不同的业务访问不同的 ...
- JAVA分布式篇2——Zookeeper
JAVA分布式篇2--Zookeeper 1.简介 Zookeeper是一个开源的分布式(多台服务器干一件事)的,为分布式应用提供协调服务的 Apache项目 2.工作机制 Zookeeper从设计模 ...
- JAVA分布式篇1——Linux
JAVA分布式篇1--Linux 1.linux命令 1.1.常用指令 ls 显示文件或目录 -l 列出文件详细信息l(list)-a 列出当前目录下所有文件及目录,包括隐藏的a(all) mkdir ...
- java分布式服务框架Dubbo的介绍与使用
1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需 ...
- Java分布式架构, Dubbo面试题汇总
Dubbo是国内最出名的分布式服务框架,也是 Java 程序员必备的必会的框架之一.Dubbo 更是中高级面试过程中经常会问的技术,无论你是否用过,你都必须熟悉. 下面我为大家准备了一些 Dubbo ...
- java 分布式介绍
java分布式服务框架Dubbo的介绍与使用 1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就 ...
- Java分布式锁看这篇就够了,java基础面试笔试题
我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...
最新文章
- 贪吃蛇计时器怎么编写java_java编写简易贪吃蛇游戏
- Codevs 5590 A+B 问题 超级版
- 大数据学习——sparkRDD
- 如何节省 1TB 图片带宽?解密极致图像压缩
- Android Studio 1.1.0 导入eclipse android project
- Millenium Leapcow POJ - 2111 (千禧年跳牛)(贪心找最长路径,记忆化)
- 参数化测试 junit_参数化的JUnit测试
- ArcGIS中的WKID(转)
- linux分割图片软件,桌面应用|5 种拆分 Linux 终端的方法
- python利用tensorflow识别圆_RaspberryPi上实现佩戴口罩识别——2020电赛F题小记
- java 找不到符号 con_我的java程序运行时,提示找不到符号,求解!
- 使用yarn运行react项目指令_Jenkins | 使用yarn构建前端项目
- SharePoint2010企业开发最佳实践(八)---- SPWeb 对象
- Android中怎么方便的调试关机充电
- javascript获取浏览器窗口大小 获取屏幕,浏览器,网页高度宽度
- treeTable树结构表格的使用
- 神舟七号飞船应用计算机进行飞行状态属于,“神舟七号”飞船应用计算机进行飞行状态调整属于()。...
- 【虚拟机装黑苹果(第一弹)】DiskMaker X制作macOS Mojave 10.14.x的U盘启动盘
- 什么是云服务举例说明_什么是云服务(什么是云服务举例说明)
- c语言怎么让程序停止3秒,求助!!!!用单片机的定时器T1怎么写一个LED亮2秒灭3秒的程序 C语言...
热门文章
- [转载] Python 迭代器 深入理解 与应用示例
- 带有示例的Python date strftime()方法
- 把百度网站设为首页_网站百度推广效果好不好?怎样才能把网站推广到百度首页?...
- web api添加拦截器
- 局域网在线监控设备扫描工具V1.0软件说明
- yolov5的flask部署python调用
- 精通ASP.NET MVC ——模型验证
- c语言程序设计教程本科,新编C语言程序设计教程(本科)第5篇.pdf
- layui表单的ajax联动,layui的select联动实现代码
- linux ptrace 读内存,Linux高级调试与优化——ptrace