一、系统架构的发展史
(1)单一应用架构
在单一应用架构下,系统所有模块都集中在一个项目下。如果网站的流量不大的时候,这种架构可以减少部署的节点和成本。
缺点:当项目规模越来越大的时候,项目维护的难度也会变得越来越大。
(2)垂直应用架构
把一个系统的拆分成若干个不同的子系统,从而提高系统运行效率和系统维护性。比较典型的应用就是网站前台和后台的分离。
缺点:这种架构下不同子系统会存在许多重复代码,代码复用性和维护性很差。
(3)分布式RPC应用架构
当垂直应用越来越多的时候,应用之间的交互也会越来越多。此时用于提高业务代码复用性以及业务功能的整合成为关键性问题。所以,在分布式应用架构中,将核心业务抽取出来,形成一个个独立的服务。服务与服务之间通过RPC进行交互。
缺点:这种架构仅仅简化了A服务和B服务之间的调度和数据传输的实现难度,提高了开发效率。当时它并没有在系统层面去保证整个系统的可用性。
(4)SOA应用架构
由于分布式RPC架构并没有在系统层面去保证整个系统的可用性,后来人们在RPC基础上又引入了许多与分布式服务治理相关的相关的组件。在这些组件里面对应用与应用之间,服务与服务之间的服务注册、服务发现、消息序列化、消息跟踪等提供了大量的工具。我们把这种架构称为面向服务架构(SOA)。现在流行的微服务架构也是在SOA的基础上发展起来的。
二、Dubbo入门
2.1 Dubbo是什么?
- 一款分布式服务框架
- 基于二进制的RPC远程调用的容器
- SOA服务治理方案(它提供了智能容错、负载均衡、实现服务注册和服务发现等功能)
2.2 Dubbo的优缺点
优点:
- 透明化的远程调用
- 软负载均衡和容错机制
- 服务注册中心自动注册和配置管理
- 服务接口监控与治理
缺点:只支持Java语言。
2.3 Dubbo的基本架构
(1) Dubbo架构中的成员:
- consumer:服务消费者。
- provider:服务提供者。
- Registry:注册中心,负责服务地址的注册和查找。
- Monitor:监控中心,负责统计各个服务的调用次数、调用时间等等的一些KPI参数。
(2)Dubbo服务调用的流程
- 服务提供者向注册中心注册服务;
- 服务消费者从注册中心获取能够提供服务的地址列表;
- 服务消费者从地址列表选取一个地址,然后再去调用该地址对应的主机服务。如果调用失败,那么消费者就会从地址列表中选取另外一个地址重新调用;
- 服务消费者和提供者统计服务的调用时间和调用次数等信息,定时发送给监控中心;
2.3 Dubbo入门示例
2.3.1 安装Zookeeper
Zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。在分布式应用中可以很好地作为Dubbo的注册中心。
(1)Zookeeper的下载和安装
下载地址:http://www.apache.org/dist/zookeeper/
zookeeper的安装非常简单,直接解压缩即可。解压后的目录结构如下图所示:
(2)启动zookeeper
第一步:进入zookeeper的conf目录,复制zoo_sample.cfg文件,并且改名为zoo.cfg。
下面是一些配置参数说明:
zookeeper提供了默认的配置模版。一般来说我们可以使用它提供的配置模版启动zookeeper。
第二步:在命令行进入zookeeper的bin目录,然后执行zkServer.cmd命令即可。
2.3.2 创建Maven项目
(1)服务提供者
第一步:新建一个Maven项目。
第二步:添加相关依赖。
服务提供者需要的依赖有:spring、dubbo、zookeeper、zkclient、netty。
完整的POM文件如下所示:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xjy</groupId>
<artifactId>dubbo-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>dubbo-provider</name>
<url>http://maven.apache.org</url>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- spring版本号 -->
<spring.version>4.3.8.RELEASE</spring.version>
<!-- log4j日志包版本号 -->
<slf4j.version>1.7.18</slf4j.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- 添加spring核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 添加日志相关jar包 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- dubbo相关jar包 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.0</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
<version>3.2.0.Final</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.11</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
第三步:定义业务接口和实现类。
定义接口类:
package com.xjy.dubbo.service;
public interface IBiz {
String sayHello(String name);
}
定义实现类:
package com.xjy.dubbo.service.impl;
import com.xjy.dubbo.service.IBiz;
public class BizImpl implements IBiz {
public String sayHello(String name) {
return "hello " + name;
}
}
第四步:配置Dubbo。
在项目src目录下新建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"
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-admin 或 dubbo-monitor 会显示这个名字,方便辨识-->
<dubbo:application name="demotest-provider" owner="programmer" organization="none"/>
<!--使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper-->
<dubbo:registry address="zookeeper://localhost:2181"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!--使用 dubbo 协议实现定义好的 api.PermissionService 接口-->
<dubbo:service interface="com.xjy.dubbo.service.IBiz" ref="biz" protocol="dubbo" />
<!--具体实现该接口的 bean-->
<bean id="biz" class="com.xjy.dubbo.sevice.impl.BizImpl"/>
</beans>
第五步:启动远程服务。
public class App {
public static void main(String[] args) throws IOException {
// 加载配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dubbo-provider.xml");
// 启动容器
context.start();
System.out.println("服务已经启动...");
// 下面代码用于保持服务端不关闭
System.in.read();
}
}
先启动Zookeeper服务,启动完成后再运行App主类启动服务容器。
(2)服务消费者
第一步:新建一个Maven项目,并指定使用maven-archetype-quickstart。
第二步:添加相关依赖 (与dubbo-provider项目的依赖相同)。
第三步:添加业务接口。
package com.xjy.dubbo.service;
public interface IBiz {
String sayHello(String name);
}
客户端业务接口可以从服务端拷贝过来,但是注意包名也要与服务端保持一致。
第四步:配置Dubbo。
在项目src目录下新建dubbo-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-admin 或 dubbo-monitor 会显示这个名字,方便辨识-->
<dubbo:application name="demotest-consumer" owner="programmer" organization="none"/>
<!--向 zookeeper 订阅 provider 的地址,由 zookeeper 定时推送-->
<dubbo:registry address="zookeeper://localhost:2181"/>
<!--使用 dubbo 协议调用定义好的 api.PermissionService 接口-->
<dubbo:reference id="bizService" interface="com.xjy.dubbo.service.IBiz"/>
</beans>
第五步:调用远程服务。
public class App {
public static void main(String[] args) {
// 加载配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dubbo-consumer.xml");
// 启动容器
context.start();
// 调用服务方法
IBiz bizService= context.getBean(IBiz.class);
System.out.println(bizService.sayHello("aa"));
}
}
运行上面客户端,可以在控制台上看到服务返回的结果。
2.3.3 安装Dubbo-admin
Dubbo-admin是一个用于管理Dubbo服务的控制台。它主要提供了定义路由规则、动态配置、服务查询、访问控制、权重调整、负载均衡等功能。
(1)下载dubboadmin压缩包
链接:https://pan.baidu.com/s/1W21gdNuJHUrVGMwrl9nv6g
提取码:1odo
下载完成后,直接部署在服务器中。然后启动zookeeper服务,再启动服务器。
(2)启动成功后,在浏览器上输入http://localhost:8080/dubboadmin访问管理后台页面。
用户名:root
密码:root
登录成功后,页面如下图所示:
【关于更多的Dubbo用法,可以参考网站:http://dubbo.apache.org/zh-cn/docs/user/quick-start.html】