概述
Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案、 服务治理方案。
官网:http://dubbo.apache.org/zh-cn/
特性:
- 面向接口代理的高性能RPC调用
- 智能负载均衡
- 服务自动注册与发现
- 高度可扩展能力
- 运行期流量调度
- 可视化的服务治理与运维
基本架构
协议
dubbo是框架,也是协议,它支持多种协议:dubbo , hessian , rmi , http, webservice , thrift , memcached , redis。
dubbo 官方推荐使用 dubbo 协议。dubbo 协议默认端口 20880
dubbo直连方式
直连就是直接关联呗,提供者与消费者直接沟通,没有注册中心。消费者必须指定服务提供者的访问地址url。
案例
分布式对象在网上传输一定需要序列化,实现serializable接口
提供者
依赖文件:pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--JDK1.8编译插件-->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
//实体类:订单类
//重点:使用dubbe,实体类必须序列化
public class Order implements Serializable {
private String id;
private String goodsName;
private Double price;
private String amount;
//不是必须的,目的是方便查看order对象是否已经赋值
@Override
public String toString() {
return "Order{" +
"id='" + id + '\'' +
", goodsName='" + goodsName + '\'' +
", price=" + price +
", amount='" + amount + '\'' +
'}';
}
public Order() {
}
//不是必须的,只是为了方便赋值
public Order(String id, String goodsName, Double price, String amount) {
this.id = id;
this.goodsName = goodsName;
this.price = price;
this.amount = amount;
}
//代码太多,此处省略set/get方法
}
//接口:订单接口
public interface OrderService {
Order addOrder(String id,String goodsName,Double price,String amount);
}
//接口实现类:订单接口实现类
public class OrderServiceImpl implements OrderService {
@Override
public Order addOrder(String id, String goodsName, Double price, String amount) {
Order order = new Order(id, goodsName, price, amount);
return order;
}
}
spring配置文件:orderprovider.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:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="link-order-provider"/>
<dubbo:protocol name="dubbo" port="20880" />
<dubbo:service interface="com.wkcto.dubbo.service.OrderService" ref="orderServiceImpl" registry="N/A"/>
<bean id="orderServiceImpl" class="com.wkcto.dubbo.service.impl.OrderServiceImpl" />
</beans>
测试类:测试是否可执行(这里可能出现找不到配置文件,target中找不到,解决:手动将配置文件拷贝到target/classes/路径下)
public class Test {
public static void main(String[] args) throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("orderprovider.xml");
((ClassPathXmlApplicationContext) context).start();//将服务启动
System.in.read();//一直读取配置文件,保持服务启动
}
}
消费者
依赖文件:pom.xml
<dependencies>
<dependency>
<groupId>com.wkcto.dubbo</groupId>
<artifactId>01-link-provider</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--JDK1.8编译插件-->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
//消费接口
public interface ShopService {
Order buyGoods(String id,String goodsName,Double price ,String amount);//依赖中如果引入两遍提供者,会找不到Order类
}
//消费接口实现类
public class ShopServiceImpl implements ShopService {
private OrderService orderService;
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
@Override
public Order buyGoods(String id, String goodsName, Double price, String amount) {
Order order = orderService.addOrder(id, goodsName, price, amount);
return order;
}
}
spring配置文件:consumer.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:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="link-consume-provider"/>
<dubbo:reference id="remoteOrderService" interface="com.wkcto.dubbo.service.OrderService" url="dubbo://localhost:20880" registry="N/A" />
<bean id="shopService" class="com.wkcto.dubbo.service.impl.ShopServiceImpl">
<property name="orderService" ref="remoteOrderService"/>
</bean>
</beans>
测试类:先启动提供者服务,使其一直运行,在运行本测试类
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("consumer.xml");
((ClassPathXmlApplicationContext) context).start();
ShopService shopService = (ShopService) context.getBean("shopService");
Order order = shopService.buyGoods("1", "小红帽", 2333.0, "6");
System.out.println(order.toString());
}
}
运行结果
Order{id='1', goodsName='小红帽', price=2333.0, amount='6'}
dubbo直连优化
- 使用分包,将服务接口,服务模型(公用实体类),服务异常等放在公共包中
- 服务接口尽可能大粒度,每个服务方法应该代表一个功能,而不是某一个步骤
- 每个接口都定义版本号,以区分同一接口的不同实现。
粒度可以理解为细化程度,细化程度越高,粒度越小;细化程度越低,粒度越大(还理解的不透彻…)
优化案例改造部分
公用包(服务接口,服务模型,服务异常等,这里没有配置文件)
//model层
//地址类:Address 类
public class Address implements Serializable {
private String id;
private String name;
private String city;
private String phone;
private boolean use;
//接下来就是生成set/get方法,太多就不写了
}
//订单类:Order
public class Order implements Serializable {
private String id;
private String goodsName;
private Double price;
private String amount;
//方便查看对象内容
@Override
public String toString() {
return "Order{" +
"id='" + id + '\'' +
", goodsName='" + goodsName + '\'' +
", price=" + price +
", amount='" + amount + '\'' +
'}';
}
public Order() {
}
//为了方便给对象赋值
public Order(String id, String goodsName, Double price, String amount) {
this.id = id;
this.goodsName = goodsName;
this.price = price;
this.amount = amount;
}
//然后需要生成set/get方法,这里略
}
//service层:接口
//订单接口:生成订单方法
public interface OrderService {
Order addOrder(String id, String goodsName, Double price, String amount);
}
//用户接口:查询用户地址方法
public interface UserService {
List<Address> queryAllAddress(String uid);
}
用户服务
- 依赖文件pom.xml
<dependencies>
<!-- 这里引入公用包 -->
<dependency>
<groupId>com.wkcto.dubbo</groupId>
<artifactId>03-node-interface</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
- 用户服务实现类UserServiceImpl
public class UserServiceImpl implements UserService {
@Override
public List<Address> queryAllAddress(String uid) {
List<Address> list = new ArrayList<Address>();
Address address = new Address();
if (uid.equals("1")) {
address.setId("1");
address.setCity("北京");
address.setName("第一笔消费");
address.setPhone("13500000000");
address.setUse(true);
list.add(address);
} else if (uid.equals("2")) {
address.setId("2");
address.setCity("上海");
address.setName("第二笔消费");
address.setPhone("13511111111");
address.setUse(true);
list.add(address);
}
return list;
}
}
- 用户服务配置文件userservice.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:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="04-node-orderservice"/>
<dubbo:protocol name="dubbo" port="20881" />
<dubbo:service interface="com.wkcto.dubbo.service.UserService" ref="userService" registry="N/A"/>
<bean id="userService" class="com.wkcto.dubbo.service.impl.UserServiceImpl" />
</beans>
- web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:userservice.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
订单服务
- 依赖文件pom.xml
<dependencies>
<!-- 这里引入公用包 -->
<dependency>
<groupId>com.wkcto.dubbo</groupId>
<artifactId>03-node-interface</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
- 订单服务实现类
public class OrderServiceImpl implements OrderService {
@Override
public Order addOrder(String id, String goodsName, Double price, String amount) {
Order order = new Order(id, goodsName, price, amount);
return order;
}
}
- 订单服务配置文件orderservice.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:dubbe="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbe:application name="05-node-customerservice" />
<dubbe:protocol name="dubbo" port="20882" />
<dubbe:service interface="com.wkcto.dubbo.service.OrderService" ref="orderService" registry="N/A"/>
<bean id="orderService" class="com.wkcto.dubbo.service.impl.OrderServiceImpl" />
</beans>
- 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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:orderservice.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
购买服务与实现页面
- 依赖文件pom.xml
<dependencies>
<dependency>
<groupId>com.wkcto.dubbo</groupId>
<artifactId>03-node-interface</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<!--Servlet、JSTL 依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
- 显示页面
商品页面index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
%>
<html>
<head>
<base href="<%=basePath%>">
<title>Title</title>
</head>
<body>
<script type="text/javascript">
var URL_PREFIX="${pageContext.request.contextPath}";
function buyGoods(userId,name,price,amount){
window.location.href= URL_PREFIX +"/shop/buy?userId="+userId
+"&name="+name
+"&price="+price
+"&amount="+amount;
}
function showAddress(userId){
window.location.href= URL_PREFIX +"/shop/addresses?userId="+userId;
}
</script>
<div style="margin-left:400px">
<table border="1" cellpadding="1" cellspacing="1" width="60%">
<p>商品列表</p>
<tr>
<td>iphone11</td>
<td>5000</td>
<td>8</td>
<td><a href="javascript:void(0)" onClick="buyGoods(1,'iphone11','5000','8')">购买</td>
</tr>
<tr>
<td>电视</td>
<td>2000</td>
<td>2</td>
<td><a href="javascript:void(0)" onClick="buyGoods(2,'电视','2000','2')">购买</td>
</tr>
</table>
</div>
<div style="margin-left:450px">
<a href="javascript:void(0)" onClick="showAddress(2)" >我的收件地址</a>
</div>
</body>
</html>
生成订单页面view-order.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
%>
<html>
<head>
<title>订单展示</title>
</head>
<body>
<h1>您的订单已经生成:</h1>
<h3>订单编号:${order.id}</h3>
<h3>订单金额:${order.price}</h3>
<h3>商品名称:${order.goodsName}</h3>
<h3>商品数量:${order.amount}</h3>
</body>
</html>
收货地址页面view-address.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>展示地址</title>
</head>
<body>
<h1>收货人地址如下:</h1>
<c:forEach items="${addressList}" var="address">
<h3>收货人姓名:${address.name}</h3>
<h3>收货人手机:${address.phone}</h3>
<h3>收货人城市:${address.city}</h3>
<h3>默认地址:${address.use}</h3>
<div>---------------------------------</div>
</c:forEach>
</body>
</html>
- 请求控制器
@Controller
public class ShopController {
@Autowired
private ShopService shopService;
@RequestMapping("/shop/buy")
public String buy(Model model,String userId, String name, Double price, String amount) {
Order order = shopService.createOrder(userId, name, price, amount);
model.addAttribute("order", order);
return "view-order";
}
@RequestMapping("/shop/addresses")
public String goAddress(Model model,String userId) {
List<Address> list = shopService.showAddress(userId);
model.addAttribute("addressList", list);
return "view-address";
}
}
- 业务层
接口ShopService
public interface ShopService {
Order createOrder(String uid,String goodsName,Double price,String amount);
List<Address> showAddress(String uid);
}
实现类ShopServiceImpl
public class ShopServiceImpl implements ShopService {
OrderService orderService;
UserService userService;
//配置文件中为属性通过bean生成对象需要有set方法
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public Order createOrder(String uid, String goodsName, Double price, String amount) {
Order order = orderService.addOrder(uid, goodsName, price, amount);
return order;
}
@Override
public List<Address> showAddress(String uid) {
List<Address> list = userService.queryAllAddress(uid);
return list;
}
}
- 模型层:货物类Goods
public class Goods implements Serializable {
private String uid;
private String goodsName;
private Double price;
private String amount;
//生成set/get方法,此处略
}
- 配置文件
dispatcherServlet.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.wkcto.dubbo.web"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:annotation-driven />
</beans>
shop-consumer.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:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="06-node-shopservice" />
<dubbo:reference id="remoteOrderService"
interface="com.wkcto.dubbo.service.OrderService"
url="dubbo://localhost:20882" registry="N/A" />
<dubbo:reference id="remoteUserService"
interface="com.wkcto.dubbo.service.UserService"
url="dubbo://localhost:20881" registry="N/A" />
<bean class="com.wkcto.dubbo.web.service.impl.ShopServiceImpl">
<property name="orderService" ref="remoteOrderService" />
<property name="userService" ref="remoteUserService" />
</bean>
</beans>
- web.xml
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcherServlet.xml,classpath:shop-consumer.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
dubbo常用标签
<dubbo:application name=" 服务名 “/> 声明dubbo服务名
<dubbo:protocol name=“dubbo” port=“20880” /> 声明协议与端口号
<dubbo:service interface=“接口路径” ref=“实现类id” /> 声明服务接口与接口实现
<dubbo:registry address=“zookeeper://ip:2181” /> 声明注册中心
<dubbo:reference id=” " interface="" version=“设置版本号” /> 声明引用接口,提供给bean的property;版本号是在同一接口有多个实现类时使用区分
注册中心zookeeper
Dubbo 提供的注册中心
Multicast 注册中心:组播方式
Redis 注册中心:使用 Redis 作为注册中心
Simple 注册中心:就是一个 dubbo 服务。作为注册中心。提供查找服务的功能。
Zookeeper 注册中心:使用 Zookeeper 作为注册中心
Zookeeper
Zookeeper 是一个高性能的,分布式的,开放源码的分布式应用程序协调服务。简称zk。它存放着多个服务提供者的IP地址与端口号,它将服务提供者的地址进行统一的管理
官网下载地址: http://zookeeper.apache.org/
使用Zookeeper改造dubbo案例
在上面代码基础上只需修改配置文件即可
将每个模块的服务配置文件添加
<dubbo:registry address="zookeeper://localhost:2181" />
同时将标签dubbo:service与标签dubbo:reference中的registry属性去掉,改造完成
注意:
- 使用时一定先开启zookeeper服务,在安装目录中的bin目录下zkServer.cmd;Linux系统是zkServer.sh
- 安装后做如下修改
1. bin同级目录下新建data文件夹:Linux使用mkdir 文件名 创建文件夹
2. 修改配置文件zoo.cfg(如果是zoo_sample.cfg,就拷一份修改)
第一步:将dataDir路径换成data文件夹所在路径:dataDir=D:\apache-zookeeper-3.5.6\data Linux切换到data目录下使用pwd查看路径
第二步:在clientPort的下一行添加admin.serverPort=8888
出现同一接口多个实现类解决
在标签dubbo:service 里面添加属性version写明版本号,使用标签dubbo:reference 时添加version ,表示引用的是具体的接口实现类
比如:
<dubbo:application name="08-zk-customerservice" />
<dubbo:registry address="zookeeper://localhost:2181" />
<dubbo:protocol name="dubbo" port="20882" />
<dubbo:service interface="com.wkcto.dubbo.service.OrderService" ref="orderService" version="
1.0.0"/>
<dubbo:service interface="com.wkcto.dubbo.service.OrderService" ref="orderService2" version="
2.0.0"/>
<bean id="orderService" class="com.wkcto.dubbo.service.impl.OrderServiceImpl" />
<bean id="orderService2" class="com.wkcto.dubbo.service.impl.OrderServiceImpl" />
<dubbo:application name="09-zk-shopservice" />
<dubbo:registry address="zookeeper://localhost:2181" />
<dubbo:reference id="remoteOrderService"
interface="com.wkcto.dubbo.service.OrderService" version="1.0.0"/>
<dubbo:reference id="remoteOrderService2"
interface="com.wkcto.dubbo.service.OrderService" version="2.0.0"/>
<dubbo:reference id="remoteUserService"
interface="com.wkcto.dubbo.service.UserService"/>
<bean class="com.wkcto.dubbo.web.service.impl.ShopServiceImpl">
<property name="orderService" ref="remoteOrderService" />
<property name="orderService2" ref="remoteOrderService2" />
<property name="userService" ref="remoteUserService" />
</bean>
注册中心的高可用
概念:
高可用性(High Availability):通常来描述一个系统经过专门的设计,从而减少不能提供服务的时间,而保持其服务的高度可用性。
Zookeeper 是高可用的,健壮的。Zookeeper 宕机,正在运行中的 dubbo 服务仍然可以正常访问。
健壮性
⚫ 监控中心宕掉不影响使用,只是丢失部分采样数据
⚫ 注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
⚫ 服务提供者无状态,任意一台宕掉后,不影响使用
⚫ 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
演示操作:
- 先启动 zookeeper, dubbo 服务提供者,dubbo 服务消费者。
- 测试正常访问
- 停止 zookeeper
- 测试消费者仍然可以访问提供者
监控中心
- 下载
下载监控中心:https://github.com/apache/incubator-dubbo-ops
这里下载的是源代码,需要手工编译才能使用。
2. 配置监控中心
修改配置 dubbo-admin-0.0.1-SNAPSHOT.jar\BOOT-INF\classes\application-properties 文件:
3. 运行管理后台 dubbo-admin
到 dubbo-admin-0.0.1-SNAPSHOT.jar 所在的目录。执行下面命令:
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
4. 运行 dubbo-admin 应用
1) 先启动注册中心
2) 执行提供者项目
3) java -jar dubbo-admin-0.0.1-SNAPSHOT.jar 启动 dubbo 管理后台
4)在浏览器地址栏输入 http://localhost:7001 访问监控中心-控制台。
监控中心的数据来自注册中心(Zookeeper)(配置文件中的dubbo.registry.address=zookeeper://127.0.0.1:2181)