文章目录
  1. 1. 环境准备:
  2. 2. zookeeper Install 伪分布式
  3. 3. dubbo admin 安装(web管理工具)
  4. 4. dubbo Provider Consumer 示例
    1. 4.1. Provider
    2. 4.2. Consumer
    3. 4.3. 先启动Provider,再启动Consumer

安装Dubbo,并利用zookeeper作为注册中心

Dubbo 是在阿里广泛应用的RPC框架,简单方便。zookeeper用于实现HA常用的一种方案。


环境准备:

Dubbo 首页


zookeeper Install 伪分布式

1.解压下载好的zookeeper,到服务器上,解压并重命名

1
2
3
wget http://www.apache.org/dist/zookeeper/stable/zookeeper-3.4.6.tar.gz
tar zxvf zookeeper-3.4.6.tar.gz
mv zookeeper-3.4.6 zookeeper-3.4.6-server-1

2.进入conf目录,复制配置文件,并修改参数

1
2
3
4
5
6
7
8
9
10
11
12
cp zoo_sample.cfg zoo.cfg
vi zoo.cfg

tickTime=2000
initLimit=5
syncLimit=2
dataDir=/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/data
dataLogDir=/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/logs
clientPort=2182
server.1=127.0.0.1:8880:7770
server.2=127.0.0.1:8881:7771
server.3=127.0.0.1:8882:7772

其中需要修改的 dataDir dataLogDir clientPort ,端口不能重复! 一般我喜欢在conf同级目录下 新建 datalogs 文件夹

  • 引用 http://coolxing.iteye.com/blog/1871009
    • initLimit: zookeeper集群中的包含多台server, 其中一台为leader, 集群中其余的server为follower. initLimit参数配置初始化连接时, follower和leader之间的最长心跳时间. 此时该参数设置为5, 说明时间限制为5倍tickTime, 即5*2000=10000ms=10s.
    • syncLimit: 该参数配置leader和follower之间发送消息, 请求和应答的最大时间长度. 此时该参数设置为2, 说明时间限制为2倍tickTime, 即4000ms.
    • server.X=A:B:C 其中X是一个数字, 表示这是第几号server. A是该server所在的IP地址. B配置该server和集群中的leader交换消息所使用的端口. C配置选举leader时所使用的端口. 由于配置的是伪集群模式, 所以各个server的B, C参数必须不同.

3.进入 conf/zoo.cfg 里指定的 data 文件夹,新建myid文件,用于标识此zk实例是集群中的哪一个,该数字必须和 zoo.cfg 文件中的 server.X 中的X相对应.

1
2
cd /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/data
echo "1" > myid

4.同理 cp 出 zk2 和 zk3 ,注意修改 data 、 logs、clientPort 、myid 这4个地方,然后依次启动zk ( 关闭stop 重启restart 状态status ) 并看启动情况

1
2
3
cd /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/
sh zkServer.sh start
less ./zookeeper.out

5.这时查看zk的进程,是否是预期的3个,以及状态(2个foller、1个leader)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[web@web02 bin]$ ps -ef | grep zoo
web 553 1 0 10:22 ? 00:00:01 /usr/java/jdk1.6.0_20/bin/java -Dzookeeper.log.dir=. -Dzookeeper.root.logger=INFO,CONSOLE -cp /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../build/classes:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../build/lib/*.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../lib/slf4j-log4j12-1.6.1.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../lib/slf4j-api-1.6.1.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../lib/netty-3.7.0.Final.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../lib/log4j-1.2.16.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../lib/jline-0.9.94.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../zookeeper-3.4.6.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../src/java/lib/*.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../conf: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false org.apache.zookeeper.server.quorum.QuorumPeerMain /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../conf/zoo.cfg
web 778 1 0 10:26 ? 00:00:01 /usr/java/jdk1.6.0_20/bin/java -Dzookeeper.log.dir=. -Dzookeeper.root.logger=INFO,CONSOLE -cp /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../build/classes:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../build/lib/*.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../lib/slf4j-log4j12-1.6.1.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../lib/slf4j-api-1.6.1.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../lib/netty-3.7.0.Final.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../lib/log4j-1.2.16.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../lib/jline-0.9.94.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../zookeeper-3.4.6.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../src/java/lib/*.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../conf: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false org.apache.zookeeper.server.quorum.QuorumPeerMain /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../conf/zoo.cfg
web 1167 1 0 10:37 ? 00:00:01 /usr/java/jdk1.6.0_20/bin/java -Dzookeeper.log.dir=. -Dzookeeper.root.logger=INFO,CONSOLE -cp /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../build/classes:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../build/lib/*.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../lib/slf4j-log4j12-1.6.1.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../lib/slf4j-api-1.6.1.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../lib/netty-3.7.0.Final.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../lib/log4j-1.2.16.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../lib/jline-0.9.94.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../zookeeper-3.4.6.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../src/java/lib/*.jar:/home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../conf: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false org.apache.zookeeper.server.quorum.QuorumPeerMain /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../conf/zoo.cfg
web 6057 2023 0 15:47 pts/6 00:00:00 grep zoo

[web@web02 bin]$ sh /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/zkServer.sh status
JMX enabled by default
Using config: /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-1/bin/../conf/zoo.cfg
Mode: follower

[web@web02 bin]$ sh /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/zkServer.sh status
JMX enabled by default
Using config: /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-2/bin/../conf/zoo.cfg
Mode: follower

[web@web02 bin]$ sh /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/zkServer.sh status
JMX enabled by default
Using config: /home/web/xiaolong.yuanxl/zookeeper-3.4.6-server-3/bin/../conf/zoo.cfg
Mode: leader

dubbo admin 安装(web管理工具)

由于dubbo官网已经打不开了,这里是我的云盘 共享

官网给出的 zk安装

官网给出的 dubbo-admin安装

1.下载并将 tomcat 解压,删除默认的 webapp/ROOT (也可以通过设置 tomcat的 server.xml 里 Context 来指定路径)

1
2
3
wget http://www.apache.org/dist/tomcat/tomcat-6/v6.0.41/bin/apache-tomcat-6.0.41.tar.gz
tar zxvf apache-tomcat-6.0.41.tar.gz
rm -rf webapps/ROOT

2.下载并解压 dubbo-admin ,并修改配置 (我指定了其中的一个zk实例),默认用户名和密码都是root

1
2
3
4
mkdir ./apache-tomcat-6.0.41/webapps/ROOT
cp dubbo-admin-2.5.4.war ./apache-tomcat-6.0.41/webapps/ROOT
jar -xvf dubbo-admin-2.5.4.war
rm -rf dubbo-admin-2.5.4.war
1
2
3
4
5
vi webapps/ROOT/WEB-INF/dubbo.properties

dubbo.registry.address=zookeeper://127.0.0.1:2182
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest

3.浏览器访问,我这里修改了tomcat端口,默认http路由的是8080端口


dubbo Provider Consumer 示例

即官网 首页示例

Provider

DemoService.java
1
2
3
4
5
6
7
package com.yxl.provider;

public interface DemoService {

String sayHello(String name);

}
DemoServiceImpl.java
1
2
3
4
5
6
7
8
9
10
package com.yxl.provider;

public class DemoServiceImpl implements DemoService {

@Override
public String sayHello(String name) {
return "Hello " + name;
}

}

Provider 配置文件

provider.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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="hello-world-app" />

<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://116.211.20.207:2182?backup=116.211.20.207:2183,116.211.20.207:2184" />

<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />

<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.yxl.provider.DemoService" ref="demoService" />

<!-- 和本地bean一样实现服务 -->
<bean id="demoService" class="com.yxl.provider.DemoServiceImpl" />

</beans>

启动 Provider

Provider.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.yxl.main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Provider {

public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "provider.xml" });
context.start();

System.in.read();
}

}

Consumer

为了便于测试,建立线程,轮询调用Provider

LogicThread.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.yxl.consumer;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

import com.yxl.provider.DemoService;
import com.yxl.util.SpringBeanHelper;

public class LogicThread implements Runnable{

private static AtomicInteger ai = new AtomicInteger(1);

@Override
public void run() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DemoService demoService = (DemoService) SpringBeanHelper.getBean("demoService");
String hello = demoService.sayHello("world");


System.out.println(sdf.format(new Date()) + " = " + ai.getAndIncrement() + " : " + hello);
}

}

建立个工具类,以便在线程里面获取bean

SpringBeanHelper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.yxl.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;

public class SpringBeanHelper{

private static ApplicationContext context;

/**
* 手工获取bean
*/

public static Object getBean(String beanId) {
return context.getBean(beanId);
}


public static void setApplicationContext(ApplicationContext ctx)
throws BeansException {

context = ctx;
}

}

Consumer配置文件

consumer.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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="consumer-of-helloworld-app" />

<!-- 使用zookeeper注册中心暴露发现服务地址 -->
<dubbo:registry address="zookeeper://116.211.20.207:2182?backup=116.211.20.207:2183,116.211.20.207:2184" />

<!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:reference id="demoService" interface="com.yxl.provider.DemoService" />

</beans>

启动Consumer

Consumer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.yxl.main;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.yxl.consumer.LogicThread;
import com.yxl.util.SpringBeanHelper;

public class Consumer {

// 初始延迟1秒
private static long INIT_DELAY = 1;

// 30秒周期
private static long PERIOD = 5;

// 初始化1个定时线程池
private static ScheduledExecutorService service = Executors
.newScheduledThreadPool(1);


public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "consumer.xml" });

SpringBeanHelper.setApplicationContext(context);

service.scheduleAtFixedRate(new LogicThread(), INIT_DELAY,
PERIOD, TimeUnit.SECONDS);

context.start();

}
}

先启动Provider,再启动Consumer

此时能看到有生产者和消费者,以及输出. 代码在 Github 你可以 git clone 然后 mvn eclipse:eclipse获取依赖,运行demo