安装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();
                }
            }