安装dubbox
安装zookeeper(单机模式)
-----------------------------------------
启动zookeeper
进入到zookeeper安装目录的bin目录,使用管理员方式运行zkServer.cmd
如果出现 "windows安全警报" 的防火墙提示界面, 点击"允许访问"
安装zookeeper为windows服务
1.
将文件prunsrv.exe,prunmgr.exe,zkServerStop.cmd,install.bat
复制到 zookeeper的bin目录下
2.
修改zkServerStop.cmd,install.bat中的zookeeper安装路径,即这行代码等号后面的值
点击文件 -> 右键 -> 编辑 或者notepad++打开 ->进行修改
set ZOOKEEPER_HOME=
使用zookeeper客户端工具
解压缩ZooInspector.zip
进入解压缩文件夹的build目录
创建一个文件 startup.bat
文件里面填写如下内容
java -jar zookeeper-dev-ZooInspector.jar
为startup.bat创建桌面快捷方式
安装maven
-----------------------------------------
下载maven
https://archive.apache.org/dist/maven/maven-3/
安装maven
解压缩
进入文件夹,
创建文件夹repo
修改conf下settings.xml,设置本地仓库,添加其他远程仓库
安装dubbox
-----------------------------------------
下载dubbox
https://github.com/dangdangdotcom/dubbox
https://github.com/dangdangdotcom/dubbox/releases (下载2.8.4版本)
点击按钮"Clone or Download"下载
安装dubbox
其实是将dubbox打包到本地maven仓库中,因为dubbox在中央仓库没有提供jar包下载
下载后,解压成文件夹
进入文件夹,执行如下命令(maven安装的bin目录路径 必须先加入到环境变量PATH中)
mvn install -Dmaven.test.skip=true
dubbo和dubbox
dubbo是alibaba开源的一个分布式服务框架
dubbox是当当网在dubbo的基础之上开发的框架
提供了一些新功能,REST风格远程调用、Kryo/FST序列化
dubbo的架构
节点说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器。
-----------------------Registry(注册中心)------------------------
| |
| |
Consumer Provider
(服务消费方) (服务提供方)
| |
| |
-----------------------Monitor(注册中心)-------------------------
调用关系说明:
0. 服务容器负责启动,加载,运行服务提供者。
1. 服务提供者在启动时,向注册中心注册自己提供的服务。
2. 服务消费者在启动时,向注册中心订阅自己所需的服务。
3. 注册VC提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
连通性:
注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销
服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销
注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外
注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
注册中心和监控中心都是可选的,服务消费者可以直连服务提供者
健状性:
监控中心宕掉不影响使用,只是丢失部分采样数据
数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
注册中心对等集群,任意一台宕掉后,将自动切换到另一台
注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
服务提供者无状态,任意一台宕掉后,不影响使用
服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
分布式服务架构
当业务变得复杂庞大之后,必须对业务进行拆分,拆分成多个子系统
每个子系统提供单独的服务接口,供其他子系统进行调用
做到低耦合高内聚
避免 多个子系统对同一个模块,比如说同一个数据库表,
进行不同的数据操作,造成最终对外提供的数据不一致
收敛入口,对这个数据库表的操作 提供一个统一的服务接口,
多个系统只能通过这个服务接口进行调用,不能直接操作数据库表
[
高内聚/低耦合
模块的功能尽量单一,提供模块的功能的相关度,模块内的功能高内聚,模块之间低耦合
例子:
商品系统 开始有品牌,供应商,
把品牌,供应商拆分出去,剩下的商品系统都是商品相关的功能,相关度变高
]
dubbo管控台
下载dubbox的源代码,使用mvn命令编译打包之后,
在本地仓库的 com/alibaba/dubbo-admin/2.8.4 文件夹下面有一个war包dubbo-admin-2.8.4.war
将这个war包复制到tomcat的webapps下面
启动tomcat
在浏览器访问 http://localhost:8080/dubbo-admin-2.8.4
输入用户名密码 root,root
dubbox监控中心
下载dubbox的源代码,使用mvn命令编译打包之后,
在本地仓库的 com/alibaba/dubbo-monitor-simple/2.8.4 文件夹下面有一个压缩包dubbo-monitor-simple-2.8.4-assembly.tar.gz
解压缩,
修改配置文件conf/dubbo.properties,
主要是dubbo.registry.address,dubbo.jetty.port(不要和tomcat冲突0
—————————————————————————–
dubbo.container=log4j,spring,registry,jetty
dubbo.application.name=simple-monitor
dubbo.application.owner=
#dubbo.registry.address=multicast://224.5.6.7:1234
dubbo.registry.address=zookeeper://127.0.0.1:2181?client=zkclient
#dubbo.registry.address=redis://127.0.0.1:6379
#dubbo.registry.address=dubbo://127.0.0.1:9090
dubbo.protocol.port=7070
dubbo.jetty.port=8088
dubbo.jetty.directory=${user.home}/monitor
dubbo.charts.directory=${dubbo.jetty.directory}/charts
dubbo.stat
istics.directory=${user.home}/monitor/statistics
dubbo.log4j.file=logs/dubbo-monitor-simple.log
dubbo.log4j.level=WARN
点击bin/startup.bat启动
在浏览器访问 http://localhost:8088/
在项目中配置dubbo添加监控中心的配置
<!-- dubbo监控中心 -->
<!-- protoco="registry"指在注册中心自动查找监控服务 -->
<dubbo:monitor protocol="registry"/>
dubbox开发demo
1.创建一个facade工程
接口
com.oldnoop.facade.HelloFacade
---------------------------------------------------------
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
@Path("/helloService")
@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
@Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})
public interface HelloFacade {
@GET
@Path("/hello/{word}")
public String hello(@PathParam("word") String word);
}
2.创建一个service工程
service实现类
com.oldnoop.service.HelloService
---------------------------------------------------------
import org.springframework.stereotype.Service;
import com.oldnoop.facade.HelloFacade;
@Service("helloService")
@com.alibaba.dubbo.config.annotation.Service(interfaceClass = HelloFacade.class, protocol = {
"rest", "dubbo" })
public class HelloService implements HelloFacade {
@Override
public String hello(String word) {
return "hello:"+word;
}
}
dubbo服务提供方配置文件
spring-dubbo-provider.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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<dubbo:application name="hello-service" owner="programmer"
organization="dubbox" />
<!-- zookeeper注册中心 -->
<dubbo:registry address="zookeeper://localhost:2181" />
<dubbo:annotation package="com.oldnoop.service" />
<!-- kryo实现序列化 -->
<dubbo:protocol name="dubbo" port="20881" serialization="kryo" />
<!-- rest -->
<dubbo:protocol name="rest" server="tomcat" port="8881"
contextpath="hello-service" threads="500" accepts="500" />
</beans>
dubbo服务启动
com.oldnoop.service.test.HelloServiceProvider
---------------------------------------------------------
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloServiceProvider {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "spring-dubbo-provider.xml" });
context.start();
System.in.read(); // 为保证服务一直开着,利用输入流的阻塞来模拟
}
}
3.创建一个consumer工程
dubbo服务消费方配置文件
spring-dubbo-consumer.xml
---------------------------------------------------------
<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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<!-- 消费服务名称 -->
<dubbo:application name="hello-consumer" owner="programmer"
organization="dubbox" />
<!-- zookeeper注册中心 zookeeper://192.168.1.111:2181 -->
<dubbo:registry address="zookeeper://localhost:2181" />
<!-- 扫描dubbox注解位置 -->
<dubbo:annotation package="com.oldnoop" />
<!-- kryo实现序列化 -->
<dubbo:protocol name="dubbo" serialization="kryo" />
<!-- 远程服务接口配置 -->
<!-- 服务接口 -->
<dubbo:reference interface="com.oldnoop.facade.HelloFacade"
id="helloFacade" />
</beans>
dubbo消费方调用服务测试
com.oldnoop.consumer.ServiceConsumer
---------------------------------------------------------
import org.springframework.context.support.ClassPathX=mlApplicationContext;
import com.oldnoop.facade.HelloFacade;
public class ServiceConsumer {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "spring-dubbo-consumer.xml" });
context.start();
HelloFacade hf = (HelloFacade) context.getBean("helloFacade");
String result = hf.hello("dubbo");
System.out.println(result);
System.in.read();
}
}