Dubbo是什么
目录
相关名词解释
RPC:Remote Produedure Call:一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议
SOA:面向服务的体系结构面向服务的体系结构(SOA)是一种思想,一种方法论,一种分布式的服务架构.SOA解决多服务凌乱问题,SOA架构解决数据服务的复杂程度,同时SOA又有一个名字,叫做服务治理
ZooKeeper:“Zookeeper是一个高性能,分布式的,开源分布式应用协调服务。它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。
Dubbo是什么
达博是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,达博就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有达博这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架其核心部分包含:
1.远程通讯:提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求 - 响应”模式的信息交换方式。
2.集群容错:提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
3.自动发现:基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
为什么要用Dubbo
- 多种调用传输方式:HTTP方式,WebService的方式;
- 服务调用依赖关系:人工记录,查看代码分析;
- 服务调用性能监控:日志记录,人工查看时间;
- 服务与应用紧耦合:服务挂掉,应用无法可用;
- 服务集群负载配置:Nginx的配置,存在单点问题;
Dubbo有什么好处
在去选择技术框架时,技术框架最基本要解决上面现存问题,同时我们也要确认出我们的期望,要达到的目标是什么:
- 支持当前业务需求,这是最最基本的条件;
- 服务避免单点问题,去中心化;
- 服务高可用,高并发,解耦服务依赖;
- 服务通用化,支持异构系统调用服务;
- 解耦系统服务间依赖,去重复;
- 服务依赖关系自维护,可视化;
- 服务性能监控自统计,可视化;
- 服务需自带注册,发现,健康检查,负载均衡等特性;
- 开发人员关注度高,上手快;
Dubbo调用过程
应用执行过程大致如下:
- 服务提供者启动,根据协议信息绑定到配置的IP和端口上,如果已有服务绑定过相同的IP和端口的则跳过
- 注册服务信息至注册中心客户端启动,根据接口和协议信息订阅注册中心中注册的服务,注册中心将存活的服务地址通知到客户端,当有服务信息变更时客户端可以通过定时通知得到变更信息
- 在客户端需要调用服务时,从内存中拿到上次通知的所有存活服务地址,根据路由信息和负载均衡机制选择最终调用的服务地址,发起调用
Dubbo入门搭建
了解了达博以后,自然要搭建一个简单的演示实现。本文采用达博与动物园管理员,春天框架的整合。
主要是以下几个步骤:
1.安装Zookeeper,启动;
2.创建MAVEN项目,构建Dubbo + Zookeeper + Spring实现的简单Demo;
3.安装Dubbo-admin,实现监控。
1.Zookeeper介绍与安装
本演示中的达博注册中心采用的是动物园管理员。为什么采用动物园管理员呢?
Zookeeper是一个分布式的服务框架,是树型的目录服务的数据存储,能做到集群管理数据,这里能很好的作为Dubbo服务的注册中心。
达博能与动物园管理员做到集群部署,当提供者出现断电等异常停机时,动物园管理员注册中心能自动删除提供者信息,当提供者重启时,能自动恢复注册数据,以及订阅请求
具体的安装方法在此不一一叙述,可参考博文: http :
//blog.csdn.net/tlk20071/article/details/52028945安装完成后,进入到bin目录,并且启动zkServer.cmd,这个脚本中会启动一个java进程:(
注:需要先启动zookeeper后,后续dubbo demo代码运行才能使用zookeeper注册中心的功能)
2.创建MAVEN项目
项目结构:
主要分三大模块:
dubbo-server-api:存放公共接口;
dubbo-client:调用远程服务;
dubbo-server:提供远程服务。
2.1首先,创建一个maven父项目,然后在父项目下创建三个子项目
2.2创建服务方项目dubbo-server
2.3在pom.xml中构建项目依赖
<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>
<artifactId>dubbo-server</artifactId>
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>tdh.platform.dubbo.demo</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<properties>
<workspace.root>${project.basedir}/../</workspace.root>
<jackson.version>2.9.0</jackson.version>
<resteasy.version>3.1.4.Final</resteasy.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.2.8.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
<artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
<version>1.0.1.Beta1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency> -->
<!-- <groupId>org.mybatis.spring.boot</groupId> -->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId> -->
<!-- <version>1.0.1</version> -->
<!-- </dependency> -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.18.1-GA</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware.kryo</groupId>
<artifactId>kryo</artifactId>
<version>2.24.0</version>
</dependency>
<dependency>
<groupId>de.javakaffee</groupId>
<artifactId>kryo-serializers</artifactId>
<version>0.26</version>
</dependency>
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- jboss resteasy -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>tdh.platform.dubbo.demo</groupId>
<artifactId>dubbo-server-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.2.7.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>${project.basedir}/bin</directory>
<filtering>true</filtering>
<includes>
<include>start.sh</include>
</includes>
<targetPath>${project.basedir}/</targetPath>
</resource>
</resources>
</build>
<version>0.0.1-SNAPSHOT</version>
<groupId>tdh.platform.dubbo.demo</groupId>
</project>
2.3在org.dubbo.server包下创建App.java
package org.dubbo.server;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
2.4在tdh.platform.dubbo.demo.impl下创建DemoServiceImpl和Provider
package tdh.platform.dubbo.demo.impl;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.dubbo.rpc.RpcContext;
import tdh.platform.dubbo.demo.DemoService;
public class DemoServiceImpl implements DemoService {
public List<String> getPermissions(Long id) {
List<String> demo = new ArrayList<String>();
demo.add(String.format("Permission_%d", id - 1));
demo.add(String.format("Permission_%d", id));
demo.add(String.format("Permission_%d", id + 1));
Boolean isComnsumerSide = RpcContext.getContext().isConsumerSide();
String serverIp = RpcContext.getContext().getRemoteHost();
String serverAddress = RpcContext.getContext().getRemoteAddressString();
String serverName = RpcContext.getContext().getRemoteHostName();
String application = RpcContext.getContext().getUrl().getParameter("application");
demo.add(serverIp);
demo.add(serverAddress);
demo.add(serverName);
demo.add(application);
return demo;
}
}
package tdh.platform.dubbo.demo.impl;
import java.io.IOException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Provider {
public static void main(String[] args) throws IOException {
// ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("provider.xml");
System.out.println(context.getDisplayName() + ": here");
context.start();
System.out.println("服务端启动...");
System.in.read();
}
}
2.5在org.dubbo.server下创建AppTest.java
package org.dubbo.server;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}
2.6在资源包下创建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="dubbox"/>
<!--使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper-->
<dubbo:registry address="zookeeper://192.168.71.211:2181?backup=192.168.71.211:2182"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!--使用 dubbo 协议实现定义好的 api.PermissionService 接口-->
<dubbo:service interface="tdh.platform.dubbo.demo.DemoService" ref="DemoService" protocol="dubbo" />
<!--具体实现该接口的 bean-->
<bean id="DemoServiceImpl" class="tdh.platform.dubbo.demo.impl.DemoServiceImpl"/>
</beans>
3.1创建项目dubbo-server-api
3.2在org.dubbo.server.api下创建App.java
package org.dubbo.server.api;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
3.3在tdh.platform.dubbo.demo下创建DemoService.java
package tdh.platform.dubbo.demo;
import java.util.List;
public interface DemoService {
List<String> getPermissions(Long id);
}
3.4在org.dubbo.server.api下创建AppTest.java
package org.dubbo.server.api;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}
4.1创建项目达博客户端
4.2在org.dubbo.client下创建App.java
package org.dubbo.client;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
4.3在tdh.paltform.dubbo.demo下创建Consumer.java
package tdh.paltform.dubbo.demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import tdh.platform.dubbo.demo.DemoService;
public class Consumer {
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("consumer.xml");
context.start();
System.out.println("consumer start");
DemoService demoService = context.getBean(DemoService.class);
System.out.println("consumer");
System.out.println(demoService.getPermissions(1L));
}
}
4.4在org.dubbo.client下创建AppTest.java
package org.dubbo.client;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}
4.5在资源包下创建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="demotest-consumer" owner="programmer" organization="dubbox"/>
<!--向 zookeeper 订阅 provider 的地址,由 zookeeper 定时推送-->
<dubbo:registry address="zookeeper://192.168.71.211:2181?backup=192.168.71.211:2182"/>
<!--使用 dubbo 协议调用定义好的 api.PermissionService 接口-->
<dubbo:reference id="DemoService" interface="tdh.paltformdubbo.demo.DemoService"/>
</beans>