1 SOA : Service-Oriented Architecture 2
2 RPC : Remote Procedure Call Protocol 2
Dubbo第一天
- SOA : Service-Oriented Architecture
面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
面向服务架构,它可以根据需求通过网络对松散耦合的粗粒度应用组件进行分布式部署、组合和使用。服务层是SOA的基础,可以直接被应用调用,从而有效控制系统中与软件代理交互的人为依赖性。
SOA是一种粗粒度、松耦合服务架构,服务之间通过简单、精确定义接口进行通讯,不涉及底层编程接口和通讯模型。SOA可以看作是B/S模型、XML(标准通用标记语言的子集)/Web Services技术之后的自然延伸。
SOA将能够帮助软件工程师们站在一个新的高度理解企业级架构中的各种组件的开发、部署形式,它将帮助企业系统架构者以更迅速、更可靠、更具重用性架构整个业务系统。较之以往,以SOA架构的系统能够更加从容地面对业务的急剧变化。
- RPC : Remote Procedure Call Protocol
远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
OSI是Open System Interconnection的缩写,意为开放式系统互联。国际标准化组织(ISO)制定了OSI模型,该模型定义了不同计算机互联的标准,是设计和描述计算机网络通信的基本框架。OSI模型把网络通信的工作分为7层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
Dubbo是阿里巴巴开发的一个基于SOA结构基础的,实现RPC远程调用的框架.
Dubbo框架,是基于容器运行的. 容器是Spring.
在编写服务和客户端的时候, 需要注册中心实现服务的发布和订阅. 注册中心中有服务端发布的服务全部信息,包括请求地址,参数命名,参数数量,参数限制,参数是否加密等. 客户端通过注册中心订阅服务,获取服务的所有信息,实现RPC远程访问.
官方网站 : http://dubbo.io/
阿里巴巴已经将dubbo框架捐献给了Apache软件基金会.
注册中心. 是用于发布和订阅服务的一个平台.
开发服务端代码完毕后, 将服务信息发布出去. 实现一个服务的公开.
发布的信息包括但不限于: 服务端所在位置(URL), 要调用的接口命名, 接口中有什么方法, 方法需要什么参数, 方法有什么返回, 调用过程超时时长是多少, 调用过程自动重复多少次, 参数数据和返回数据长度有多少等.
客户端程序,从注册中心下载服务内容, 就是发布的服务信息. 这个过程是订阅.
订阅服务的时候, 会将发布的服务所有信息,一次性下载到客户端.
客户端也可以自定义, 修改部分服务信息. 如: 超时的时长, 调用的重复次数等.
服务的消费者, 就是服务的客户端.
消费者必须使用Dubbo技术开发部分代码. 基本上都是配置文件定义.
服务的提供者, 就是服务端.
服务端必须使用Dubbo技术开发部分代码. 以配置文件为主.
协议. 在Dubbo技术中, 客户端和服务器的通讯方式, 都是建立在协议通讯基础之上的.
dubbo技术支持若干协议. 如: dubbo协议(阿里自主开发的协议), http协议, tcp协议等.
容器. Dubbo技术的服务端(Provider), 在启动执行的时候, 必须依赖容器才能正常启动.
默认依赖的就是spring容器. 且Dubbo技术不能脱离spring框架.
在2.5.3版本的dubbo中, 默认依赖的是spring2.5版本技术. 可以选用spring4.5以下版本.
在2.5.7版本的dubbo中, 默认依赖的是spring4.3.10版本技术. 可以选择任意的spring版本.
监控中心. 是Dubbo提供的一个war工程.
主要功能是监控服务端(Provider)和消费段(Consumer)的使用数据的. 如: 服务端是什么,有多少接口,多少方法, 调用次数, 压力信息等. 客户端有多少, 调用过哪些服务端, 调用了多少次等. 也可以实现集群权重的分配.
官方推荐使用的注册中心.
Zookeeper是apache开发的一个java工程. 是hadoop工程的子工程. 主体功能是用于实现其他应用管理的一个管理平台.
核心功能是: 管理多应用, 统一管理配置信息, 名称管理服务, 分布式锁等.
管理多应用 : Apache中有若干应用, 如: hadoop, bea, pig等. 这些应用可能同时使用, 需要一个统一的管理平台, 实现管理.
统一配置 : 在商业开发中, 很可能统一个应用使用多份,如: 多个hadoop. 那么多个hadoop配置应用统一.
名称服务管理 : 商业开发中, 应用数量若干. 如: hadoop10个, pig20个, bea30个. 在记忆各个应用位置的时候,非常麻烦. 应用位置: 就是主机名(IP)+端口号. Zookeeper可以为每个应用命名, 类似域名. 方便管理和查找.
分部锁 : 如果多个同应用同时使用的时候, 不同客户端访问过程,是否有数据错误的可能. 如: 有若干hadoop, 客户端1访问hadoop1, 新增数据. 客户端2访问hadoop2,查询数据.查询的结果应该包括新增的数据. 先运行哪一个客户端请求? 保证数据结果正确性.
-
-
- multicast
-
广播实现服务发布和订阅的注册方式. 不需要启动任何的注册中心平台.
只适用于小型的项目. 在大型工程中会有通讯阻塞问题.(广播风暴.)
-
-
- redis
-
KV服务器. 高速缓存服务器. 是一个内存结构的类似数据库的缓存服务器. 也可以称为NoSQL数据库.
实际就是通过键值对的形式, 在redis中保存服务的发布数据. 客户端通过key查询value,订阅服务.
效率高, 且可搭建集群. 适用部分大型商业开发. 但是稳定性不保证.
tar -zxf xxxx.tar.gz
-
-
-
- 建议复制到/usr/local/目录中
-
-
cp -r xxx /usr/local/xxx
-
-
-
- 配置环境变量
-
-
vi /etc/profile
内容:
JAVA_HOME=XXX
CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME
export CLASSPATH
export PATH
-
-
- 安装Zookeeper
-
下载位置: zookeeper.apache.org
-
-
-
- 解压缩
-
-
tar -zxf zookeeper.tar.gz
-
-
-
- 建议复制到/usr/local目录中
-
-
cp -r zookeeper /usr/local/zookeeper
-
-
-
- 简介Zookeeper资源
- bin
- 简介Zookeeper资源
-
-
可执行文件. 启动,停止, 状态检查, 重启等功能都通过目录中的可执行文件操作.
-
-
-
-
- conf
-
-
-
配置目录. 保存所有的配置文件
-
-
-
-
- lib
-
-
-
就是Zookeeper内容. Zookeeper是java开发的, 实际上就是一组jar包. lib中的jar就是Zookeeper的源信息.
-
-
-
-
- src
-
-
-
Zookeeper提供的源代码. java开发的应用,开源免费.
-
-
-
-
- data
-
-
-
临时数据文件目录. 需要自定义. 可以定义在任意位置.
Zookeeper使用的临时数据文件目录, 是通过conf目录中的配置文件配置的.
默认是/tmp/zookeeper目录中的临时目录.
目录中保证Zookeeper运行过程的所有数据信息. 包括临时数据和持久化数据.
-
-
-
- 启动Zookeeper
-
-
执行bin目录中的可执行文件
zkServer.sh start
启动后, 会有日志文件创建. 其中保存启动日志. zookeeper.out
如果启动失败, 则在日志文件中有对应的异常堆栈信息.
-
-
-
- 停止
-
-
zkServer.sh stop
-
-
-
- 状态查看
-
-
zkServer.sh status
成功启动状态信息
启动失败的状态信息
-
-
-
- 重启
-
-
zkServer.sh restart
-
-
- 客户端访问
-
使用Zookeeper提供的默认客户端本地访问.
bin/zkCli.sh
默认连接本地服务, 端口为2181.
指定连接
bin/zkCli.sh -server ip:port
客户端命令 : Zookeeper提供了命令提示. 输入任意字符回车后有提示信息.
服务提供者开始编写. 首先开发服务的提供者, 再次发布服务. 最后由服务消费者调用服务.
<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.bjsxt</groupId> <artifactId>dubbo-provider</artifactId> <version>1.0</version> <dependencies>
<!-- dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.7</version> </dependency> <!-- zookeeper客户端 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency>
</dependencies> </project> |
-
-
- 代码
- 接口
- 代码
-
package com.bjsxt.service;
public interface UserService {
void register(String name, String password);
void login(String name, String password);
}
|
-
-
-
- 实现类
-
-
package com.bjsxt.service.impl;
import org.springframework.stereotype.Service;
import com.bjsxt.service.UserService;
/** * 不考虑dubbo的任何问题. 正常开发 * 只考虑spring管理的问题. * spring容器管理服务对象. * 1. bean标签管理 * 2. 注解管理 * 使用注解管理, 容易导包错误. Dubbo也提供了service注解. 但是dubbo的service注解 * 有代码冲突. 在大多数情况下. 和spring-context, spring-tx有冲突. * Dubbo的service注解, 在2.5.3版本中(使用spring2.5)注解无冲突. */
@Service public class UserServiceImpl implements UserService {
@Override public void register(String name, String password) { System.out.println("register : " + name + " ; " + password); }
@Override public void login(String name, String password) { System.out.println("login : " + name + " ; " + password); }
}
|
描述自定义的Provider和注册中心的信息.
本地开发的服务代码是什么, 注册中心种类和位置是什么.
dubbo没有自定义的配置文件. 使用的都是spring的配置文件.
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" 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://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- dubbo配置. Dubbo的配置信息,必须导入新的namespace. namespace可以通过dubbo的jar包查询. 配置文件的约束信息所在位置: dubbo.jar/META-INF/dubbo.xsd --> <!-- 1. 配置dubbo的应用名称, 是为一个Dubbo的Provider或Consumer在注册中心中定义唯一命名. 且在monitor监控中心中可以根据应用名称查看应用统计信息. --> <dubbo:application name="test-provider-001"/>
<!-- 2. 配置注册中心. 是定义注册中心Zookeeper所在的位置和使用的协议. 协议名称就是zookeeper, 地址是IP:port --> <dubbo:registry address="192.168.120.143:2181" protocol="zookeeper"/>
<!-- 3. 配置协议信息. 是配置,在发布的服务中,绑定的协议是什么. 也就是Consumer使用什么协议访问Provider --> <dubbo:protocol name="dubbo" port="20880"/>
<!-- 4. 配置具体的要发布的服务信息. 发布的服务是协议内容. 就是 - 协议://ip:port/接口名称?方法&参数&其他配置等 发布的服务, 在订阅后,必须配合具体的服务的接口,才能使用. 不需要实现类. 发布的服务虽然是协议内容, 但是必须由具体的要发布的服务接口的实现类提供服务的实现. 所以需要引用一个有效的service对象. ref - 具体的提供服务的实现类对象. 是spring容器管理的对象. 使用bean对象命名查询的. interface - 接口. 代表发布的服务绑定的接口类型是什么. --> <dubbo:service ref="userServiceImpl" interface="com.bjsxt.service.UserService"/>
<!-- 扫描spring的注解, 创建service对象. --> <context:component-scan base-package="com.bjsxt.service"></context:component-scan>
</beans> |
-
-
- 协议类型
-
Dubbo中支持多种协议. 推荐使用dubbo协议.
-
-
-
- dubbo
-
-
Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
单一长连接 - 客户端服务器连接只建立一次. 建立成功后必须访问结束才断开.
NIO异步通讯 - 提高效率的方式. 可以让客户端和服务器同时发送和接收数据.
限制:
不适合传递大数据. 如: 文件.
使用Dubbo协议的时候, 服务中方法的参数和返回值类型都必须可序列化. 因为Dubbo协议采用tcp+hessian协议配合实现数据传递. hessian协议要求必须传递的数据都可序列化.
-
-
-
- rmi
-
-
远程方法调用接口. 是JDK定义的远程调用协议. 采用阻塞式短连接和JDK标准序列化方式.
阻塞短连接 - 单一连接过程中, 通讯方式为同步.
不适用于高并发的请求环境. 如: 互联网.
-
-
-
- hessian
-
-
是http协议的升级版. 是一个建立在http协议基础上的应用层协议.
要求所有的服务方法参数和返回值类型必须可序列化. 且不能传递集合等接口类型的自定义实现类. 传递的是自定义的集合接口实现类. 只序列化内容,不序列化方法.
-
-
-
- redis
-
-
是使用redis作为中间过程, 通过redis实现数据通讯的一种方式.
相对较少. 相对的稳定性无法控制.
服务消费者开发. 不需要考虑dubbo问题. 都是通过配置实现dubbo的服务订阅和应用. 将dubbo中的Provider当做是本地的一个接口应用即可.
将Provider接口作为本地对象应用. 通过spring容器注入代理对象.
代理对象由spring容器+dubbo动态创建.
-
-
- 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.bjsxt</groupId> <artifactId>dubbo-consumer</artifactId> <version>1.0</version> <dependencies>
<!-- 需要依赖服务提供者的接口. 配合订阅的服务信息,实现代理对象的创建. --> <dependency> <groupId>com.bjsxt</groupId> <artifactId>dubbo-provider</artifactId> <version>1.0</version> </dependency> <!-- dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.7</version> </dependency> <!-- zookeeper客户端 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency>
</dependencies> </project> |
-
-
- 代码
- 接口
- 代码
-
package com.bjsxt.consumer.service;
public interface UserServiceConsumer {
public void register(String name, String password);
public void login(String name, String password);
}
|
-
-
-
- 实现类
-
-
package com.bjsxt.consumer.service.impl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
import com.bjsxt.consumer.service.UserServiceConsumer; import com.bjsxt.service.UserService;
/** * 服务消费者代码. * 不考虑Dubbo的技术问题. 只考虑当前对象在spring容器中的管理问题. */ @Service public class UserServiceConsumerImpl implements UserServiceConsumer {
// 需要通过spring注入. 注入的是接口的代理对象. 由接口+订阅的服务信息+JDK的proxy实现. // 动态代理对象的具体创建逻辑.由Dubbo技术提供. // dubbo技术提供了reference注解, 替代后续定义的标签. 有代码冲突. @Autowired private UserService userService;
@Override public void register(String name, String password) { // 具体逻辑由Provider提供. System.out.println("consumer register run..."); // 调用Provider代码, 需要定义属性. 提供对象引用. this.userService.register(name, password); }
@Override public void login(String name, String password) { System.out.println("consumer login run..."); this.userService.login(name, password); }
}
|
核心标签是: <dubbo:reference interface=”” id=””/>
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" 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://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 1. 配置dubbo应用名 --> <dubbo:application name="test-consumer-001" />
<!-- 2. 配置dubbo的注册中心 --> <dubbo:registry address="192.168.120.143:2181" protocol="zookeeper" />
<!-- 3. 配置dubbo的订阅服务内容. 要订阅哪一个接口服务信息. Consumer不需要定义协议. 因为协议信息由服务的提供者定义. reference - 引用, 是要订阅注册中心中的服务信息. 订阅成功后, 在spring容器中,依赖容器和Dubbo技术,创建代理对象. 创建的代理对象命名为id属性值. 建议id属性值命名和Consumer中引用的属性名一致. interface - 要订阅的具体的服务接口命名. 就是Provider发布的服务接口命名. --> <dubbo:reference interface="com.bjsxt.service.UserService" id="userService" />
<!-- 配置扫描spring注解 --> <context:component-scan base-package="com.bjsxt.consumer.service"></context:component-scan>
</beans> |
是Dubbo框架提供的一个Main类. 其中定义了main方法.实现启动方式.
Dubbo提供的Main中,扫描的配置文件有固定位置.
配置文件固定在 classpath:META-INF/spring目录中.
配置文件类型必须是xml配置文件.
package com.bjsxt.test;
import com.alibaba.dubbo.container.Main;
public class TestMain {
public static void main(String[] args) throws Exception {
// 启动Provider Main.main(args);
// 阻塞 System.in.read();
}
}
|
常用于生产环境使用. 商业项目中最终的使用方式.
打包启动: 就是将代码打包为jar包. 并提供启动文件, 如: start.bat, start.sh等. 执行启动文件, 自动调用Main类中的main方法.
assembly打包,需要在maven中增加新的插件. 且会修改install功能.
-
-
- 导入assembly资源
-
资料/assembly/dubbo-monitor-simple-2.5.3/*
复制之前,检查conf目录中的*.properties文件. 清空文件内容.
Main类默认先查询conf目录中的properites配置,再检查META-INF/spring中的配置.
保存在工程的根目录下. 不要保存在src目录中.
-
-
- 定义assembly配置信息
-
提供一个xml配置文件. 定义assembly配置信息.
<?xml version='1.0' encoding='UTF-8'?> <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"> <!-- 该字符会添加到最终tar.gz包的名称后面,作为后缀 当前应用 : homework-provider-impl 打包后 : homework-provider-impl-assembly.tar.gz --> <id>assembly</id> <!-- 指定打包的格式为tar.gz,该类型压缩包在linux中比较常见 --> <formats> <format>tar.gz</format> </formats> <!-- 在tar.gz压缩包中是否包含根文件夹,该根文件夹名称和tar.gz去掉id后缀一致 --> <includeBaseDirectory>true</includeBaseDirectory> <fileSets> <!-- 将项目根路径下assembly/bin路径中的内容打包到压缩包中的根目录下的bin目录中 --> <fileSet> <!-- 相对项目根路径的相对路径 --> <directory>assembly/bin</directory> <outputDirectory>bin</outputDirectory> <!-- 设置最终tar.gz中该文件夹下的权限,跟linux权限写法一致 --> <fileMode>0755</fileMode> </fileSet> <!-- 将项目根路径下assembly/conf路径中的内容打包到压缩包中的根目录下的conf目录中 --> <fileSet> <directory>assembly/conf</directory> <outputDirectory>conf</outputDirectory> <!-- 设置其linux权限 --> <fileMode>0644</fileMode> </fileSet> </fileSets> <!-- 将所有依赖的jar包打包到压缩包中的根目录下的lib目录中 --> <!-- 此lib目录中包含自己开发的项目jar包以及demo_service.jar,还有第三方的jar包 --> <dependencySets> <dependencySet> <outputDirectory>lib</outputDirectory> </dependencySet> </dependencySets> </assembly> |
-
-
- 在pom文件中依赖assembly插件并应用.
-
在pom文件中新增build和plugins. 提供assembly插件配置.
<build> <plugins> <!-- 指定项目的打包插件信息, maven install 特性变更. 变化为-打包. --> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <!-- 指定打包描述文件的位置:相对项目根目录的路径 --> <!-- assembly打包的描述文件 --> <descriptor>assembly/assembly.xml</descriptor> </configuration> <executions> <execution> <id>make-assembly</id> <!-- 要执行的功能. 打包. --> <phase>package</phase> <goals> <!-- 打包文件永远是唯一的.多次打包是覆盖操作. --> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> |
-
-
- 打包
-
maven install. 安装就是打包. 安装成功后, 打包的tar.gz压缩位置在target目录中.
资料/注册中心管理项目/*.war 到tomcat/webapps目录中.
启动tomcat, 容器自动解压缩war文件. 形成对应的目录结构.
停止tomcat. 删除war文件.
war文件在webapps目录中存在的话. 每次重新启动tomcat. 重新解压缩war文件. 并覆盖对应的目录结构.
修改工程中的WEB-INF/dubbo.properties配置文件.
# 注册中心位置. 使用协议://IP:port访问. 可以传递参数. dubbo.registry.address=zookeeper://192.168.120.143:2181 # 设定监控中心访问用户. # dubbo.admin.用户名.password=密码 dubbo.admin.root.password=root dubbo.admin.guest.password=guest |
修改配置文件后, 重新启动tomcat. 并访问。