Dubbo注册中心Resitry之Redis

<dubbo:registry address="redis://10.20.153.10:6379" />
<dubbo:registry address="redis://10.20.153.10:6379?backup=10.20.153.11:6379,10.20.153.12:6379" />

<dubbo:registry protocol="redis" address="10.20.153.10:6379" />
<dubbo:registry protocol="redis" address="10.20.153.10:6379,10.20.153.11:6379,10.20.153.12:6379" />

数据结构

使用Redis的Hash结构存储数据

  • 主Key为服务名和类型。
  • Map中的Key为URL地址。
  • Map中的Value为过期时间,用于判断脏数据,脏数据由监控中心删除。

使用Redis的Publish/Subscribe事件通知数据变更

  • 通过事件的值区分事件类型:register、unregister、subscribe、unsubscribe。
  • consumer订阅指定的provider,只会收到指定provider的register、unregister事件。
  • 监控中心订阅/dubbo/*,会收到所有服务的所有变更事件。

调用过程

  • provider启动时,向Key:/dubbo/top.guoj.api.HelloService/providers下,添加当前提供者的地址。
  • 并向Channel:/dubbo/top.guoj.api.HelloService/providers发送register事件。
  • 服务消费方启动时,从Channel:/dubbo/com.foo.BarService/consumers订阅register和unregister事件。
  • 并向Key:/dubbo/com.foo.BarService/consumers下,添加当前消费者的地址。
  • 服务消费方收到register和unregister事件后,从Key:/dubbo/com.foo.BarService/providers下获取提供者地址列表。
  • 服务监控中心启动时,从Channel:/dubbo/*订阅register和unregister,以及subscribe和unsubsribe事件。
  • 服务监控中心收到register和unregister事件后,从Key:/dubbo/com.foo.BarService/providers下获取提供者地址列表。
  • 服务监控中心收到subscribe和unsubsribe事件后,从Key:/dubbo/com.foo.BarService/consumers下获取消费者地址列表。

启动provdier

127.0.0.1:6379> keys *
1) "/dubbo/top.guoj.api.HelloService/providers"
127.0.0.1:6379> type /dubbo/top.guoj.api.HelloService/providers
hash
127.0.0.1:6379> hgetall /dubbo/top.guoj.api.HelloService/providers
1) "dubbo://192.168.100.61:20880/top.guoj.api.HelloService?anyhost=true&application=demo-provider&dubbo=2.6.2&generic=false&interface=top.guoj.api.HelloService&methods=sayHello&pid=5252&side=provider&timestamp=1533106855687"
2) "1533106976445"

启动consumer

127.0.0.1:6379> keys *
1) "/dubbo/top.guoj.api.HelloService/consumers"
2) "/dubbo/top.guoj.api.HelloService/providers"
127.0.0.1:6379> type /dubbo/top.guoj.api.HelloService/consumers
hash
127.0.0.1:6379> hgetall /dubbo/top.guoj.api.HelloService/consumers
1) "consumer://192.168.100.61/top.guoj.api.HelloService?application=dubbo-consumer&category=consumers&check=false&dubbo=2.6.2&interface=top.guoj.api.HelloService&methods=sayHello&pid=7196&side=consumer&timestamp=1533107247126"
2) "1533107337246"
127.0.0.1:6379>

选项

  • 可通过<dubbo:registry group=“dubbo”/>设置redis中key的前缀,缺省为dubbo。
  • 可通过<dubbo:registry cluster=“replicate”/>设置redis集群策略,缺省为failover。
    • failover: 只写入和读取任意一台,失败时重试另一台,需要服务器端自行配置数据同步。
    • replicate: 在客户端同时写入所有服务器,只读取单台,服务器端不需要同步,注册中心集群增大,性能压力也会更大。

Dubbo注册中心Registry之Zookeeper

Zookeeper

在dubbo提供的4种注册方式中,官方推荐使用apache开源项目 Zookeeper

以服务接口为例:

<dubbo:service interface="top.guoj.api.HelloService" ref="helloService" />
  • Provider启动:在zookeeper路径/dubbo/top.guoj.api.HelloService/providers写入自己的URL地址。
  • Consumer启动:订阅/dubbo/top.guoj.api.HelloService/providers目录下的URL地址,并在/dubbo/com.foo.BarService/consumers目录写入自己的URL地址。
  • Monitor Center启动:订阅/dubbo/top.guoj.api.HelloService/consumers和/dubbo/top.guoj.api.HelloService/providers下的所有URL地址。

启动Provider

[zk: localhost:2181(CONNECTED) 46] ls /
[dubbo, zookeeper]
[zk: localhost:2181(CONNECTED) 47] ls /dubbo
[top.guoj.api.HelloService]
[zk: localhost:2181(CONNECTED) 48] ls /dubbo/top.guoj.api.HelloService
[configurators, providers]
[zk: localhost:2181(CONNECTED) 51] ls /dubbo/top.guoj.api.HelloService/providers
[dubbo%3A%2F%2F192.168.100.61%3A20880%2Ftop.guoj.api.HelloService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.6.2%26generic%3Dfalse%26interface%3Dtop.guoj.api.HelloService%26methods%3DsayHello%26pid%3D8140%26side%3Dprovider%26timestamp%3D1533023619863]

启动Consumer

[zk: localhost:2181(CONNECTED) 49] ls /dubbo/top.guoj.api.HelloService
[consumers, configurators, routers, providers]
[zk: localhost:2181(CONNECTED) 50] ls /dubbo/top.guoj.api.HelloService/consumers
[consumer%3A%2F%2F192.168.100.61%2Ftop.guoj.api.HelloService%3Fapplication%3Ddubbo-consumer%26category%3Dconsumers%26check%3Dfalse%26dubbo%3D2.6.2%26interface%3Dtop.guoj.api.HelloService%26methods%3DsayHello%26pid%3D11136%26side%3Dconsumer%26timestamp%3D1533023700514]
  • 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息。
  • 当注册中心重启时,能自动恢复注册数据,以及订阅请求。
  • 当会话过期时,能自动恢复注册数据,以及订阅请求。
  • 当设置<dubbo:registry check=“false”/>时,记录失败注册和订阅请求,后台定时重试。
  • 可通过<dubbo:registry username=“admin” password=“1234”/>设置zookeeper登录信息。
  • 可通过<dubbo:registry group=“dubbo”/>设置zookeeper的根节点,默认是dubbo。
  • 支持*号通配符<dubbo:reference group="" version=""/>,可订阅服务的所有分组和所有版本的提供者。
<dubbo:registry address="zookeeper://192.168.100.61:2181" group="test1" />
<dubbo:registry address="zookeeper://192.168.100.61:2181" group="test2" />
<bean id="helloService" class="top.guoj.provider.HelloServiceImpl" />
<dubbo:service interface="top.guoj.api.HelloService" ref="helloService" />

启动上面配置的Provider:

[zk: localhost:2181(CONNECTED) 36] ls /
[test2, zookeeper, test1]
[zk: localhost:2181(CONNECTED) 37] ls /test1/top.guoj.api.HelloService
[configurators, providers]
[zk: localhost:2181(CONNECTED) 38] ls /test2/top.guoj.api.HelloService
[configurators, providers]
[zk: localhost:2181(CONNECTED) 39] ls /test1/top.guoj.api.HelloService/providers
[dubbo%3A%2F%2F192.168.100.61%3A20880%2Ftop.guoj.api.HelloService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.6.2%26generic%3Dfalse%26interface%3Dtop.guoj.api.HelloService%26methods%3DsayHello%26pid%3D7492%26side%3Dprovider%26timestamp%3D1533023167412]
[zk: localhost:2181(CONNECTED) 40] ls /test2/top.guoj.api.HelloService/providers
[dubbo%3A%2F%2F192.168.100.61%3A20880%2Ftop.guoj.api.HelloService%3Fanyhost%3Dtrue%26application%3Ddemo-provider%26dubbo%3D2.6.2%26generic%3Dfalse%26interface%3Dtop.guoj.api.HelloService%26methods%3DsayHello%26pid%3D7492%26side%3Dprovider%26timestamp%3D1533023167412]

客户端

支持zkclientcurator两种客户端实现。从2.2.0起默认使用zkclient。2.3.0后支持curator。

zkclient

<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.1</version>
</dependency>
dubbo.registry.client=zkclient
<dubbo:registry address="zookeeper://192.168.100.61:2181" client="zkclient" />
<dubbo:registry address="zookeeper://192.168.100.61:2181?client=zkclient"/>

curator

<dependency>
    <groupId>com.netflix.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>1.1.10</version>
</dependency>
<dubbo:registry address="zookeeper://192.168.100.61:2181" client="curator" />
dubbo.registry.client=curator
<dubbo:registry address="zookeeper://192.168.100.61:2181?client=curator"/>

zookeeper单机配置

<dubbo:registry address="zookeeper://10.20.153.10:2181" />
<dubbo:registry protocol="zookeeper" address="10.20.153.10:2181" />

zookeeper集群配置

<dubbo:registry address="zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181" />
<dubbo:registry protocol="zookeeper" address="10.20.153.10:2181,10.20.153.11:2181,10.20.153.12:2181" />

Dubbo注册中心Registry之Multicast

Dubbo的注册中心Registry主要有下面四种方式,官方推荐使用Zookeeper。

Multicast

类似IP地址广播。不需要启动任何中心节点,只要广播地址一样,就可以互相发现。组播受网络结构限制,只适合小规模应用或开发阶段使用。组播地址段: 224.0.0.0 - 239.255.255.255。

  • Provider启动时,广播它的地址。

  • Consumer启动时,广播它的订阅请求。

  • 当Provider接收到订阅请求,单播自己的地址给Consumer,若unicast=false ,则使用广播给Consumer。

  • 当Consumer接收到Provider的服务地址,就可以通过收到的地址进行RPC调用。

<dubbo:registry address="multicast://224.5.6.7:1234" />

或者

<dubbo:registry protocol="multicast" address="224.5.6.7:1234" />

为了减少广播量,Dubbo默认使用单播将地址信息从Provider发送给Consumer,如果Consumer有多个进程在一个机器中,Consumer需要设定unicast=false,否则只有一个Consumer可以接收该地址信息:

<dubbo:registry address="multicast://224.5.6.7:1234?unicast=false" />

也可以这样配置

<dubbo:registry protocol="multicast" address="224.5.6.7:1234">
    <dubbo:parameter key="unicast" value="false" />
</dubbo:registry>

Dubbo管理控制台

下载代码

git clone https://github.com/apache/incubator-dubbo-ops

Maven打包

cd incubator-dubbo-ops && mvn package

修改配置\BOOT-INF\classes\application.properties

server.port=7001
spring.velocity.cache=false
spring.velocity.charset=UTF-8
spring.velocity.layout-url=/templates/default.vm
spring.messages.fallback-to-system-locale=false
spring.messages.basename=i18n/message
#root用户密码
spring.root.password=root
#guest用户密码
spring.guest.password=guest

运行

最新版已是spring boot应用程序,直接运行jar包即可。

java -jar dubbo-admin/target/dubbo-admin-0.0.1-SNAPSHOT.jar

Dubbo通讯之zookeeper

Zookeeper

zoo.cfg

tickTime=2000
initLimit=10
syncLimit=5
dataDir=/var/data/zookeeper
clientPort=2181

Maven Properties

<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<dubbo.version>2.6.2</dubbo.version>
	<zookeeper.version>3.4.6</zookeeper.version>
	<curator.version>2.8.0</curator.version>
	<log4j.version>1.2.17</log4j.version>
	<slf4j.version>1.7.2</slf4j.version>
</properties>

Provider

provider.pom

<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>top.guoj</groupId>
		<artifactId>dubbo-demo</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>top.guoj</groupId>
	<artifactId>dubbo-provider</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>dubbo-provider</name>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<version>${dubbo.version}</version>
		</dependency>
		<dependency>
			<groupId>top.guoj</groupId>
			<artifactId>dubbo-api</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>${log4j.version}</version>
			<exclusions>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>${zookeeper.version}</version>
			<exclusions>
				<exclusion>
					<groupId>log4j</groupId>
					<artifactId>log4j</artifactId>
				</exclusion>
				<exclusion>
					<groupId>io.netty</groupId>
					<artifactId>netty</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-nop</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
			<version>${curator.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-recipes</artifactId>
			<version>${curator.version}</version>
		</dependency>
	</dependencies>
</project>

provider.xml

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
	<dubbo:application name="demo-provider" />
	<dubbo:registry address="zookeeper://192.168.100.61:2181" />
	<bean id="helloService" class="top.guoj.provider.HelloServiceImpl" />
	<dubbo:service interface="top.guoj.api.HelloService" ref="helloService" />
</beans>

Consumer

consumer.pom

<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>top.guoj</groupId>
		<artifactId>dubbo-demo</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>top.guoj</groupId>
	<artifactId>dubbo-consumer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>dubbo-consumer</name>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<version>${dubbo.version}</version>
		</dependency>
		<dependency>
			<groupId>top.guoj</groupId>
			<artifactId>dubbo-api</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>${log4j.version}</version>
			<exclusions>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>${zookeeper.version}</version>
			<exclusions>
				<exclusion>
					<groupId>log4j</groupId>
					<artifactId>log4j</artifactId>
				</exclusion>
				<exclusion>
					<groupId>io.netty</groupId>
					<artifactId>netty</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-nop</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
			<version>${curator.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-recipes</artifactId>
			<version>${curator.version}</version>
		</dependency>
	</dependencies>
</project>

consumer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
	<dubbo:application name="dubbo-consumer" />
	<dubbo:registry address="zookeeper://192.168.100.61:2181" />
	<dubbo:reference id="helloService" check="false" interface="top.guoj.api.HelloService" />
</beans>

Dubbo之helloword

Dubbo是阿里开源一个分布式服务RPC框架。现已进入apache孵化。

  • Provider: 服务提供方。
  • Consumer: 服务消费方。
  • Registry: 服务注册与发现的注册中心。
  • Monitor: 统计服务的调用次调和调用时间的监控中心。
  • Container: 服务运行容器。

dubbo-demo

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>top.guoj</groupId>
	<artifactId>dubbo-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>pom</packaging>
	<name>dubbo-demo</name>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<modules>
		<module>dubbo-api</module>
		<module>dubbo-provider</module>
		<module>dubbo-consumer</module>
	</modules>
</project>

dubbo-api

├─src
│  ├─main
│  │  ├─java
│  │  │  └─top
│  │  │      └─guoj
│  │  │          └─api
│  │  └─resources
│  └─test
│      ├─java
│      └─resources
└─target
    ├─classes
    └─test-classes
  • HelloService.java
package top.guoj.api;

public interface HelloService {
	String sayHello(String name);
}
  • pom.xml
<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>top.guoj</groupId>
		<artifactId>dubbo-demo</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>top.guoj</groupId>
	<artifactId>dubbo-api</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>dubbo-api</name>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
	</dependencies>
</project>

dubbo-provider

├─src
│  ├─main
│  │  ├─java
│  │  │  └─top
│  │  │      └─guoj
│  │  │          └─provider
│  │  └─resources
│  └─test
│      ├─java
│      └─resources
└─target
    ├─classes
    └─test-classes
  • HelloServiceImpl.java
package top.guoj.provider;

import top.guoj.api.HelloService;

public class HelloServiceImpl implements HelloService {

	@Override
	public String sayHello(String name) {
		return "hello dubbo";
	}

}
  • Provider.java
package top.guoj.provider;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Provider {

    public static void main(String[] args) throws Exception {
        System.setProperty("java.net.preferIPv4Stack", "true");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"provider.xml"});
        context.start();
        System.out.println("Provider started.");
        System.in.read(); 
    }
}
  • provider.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

	<!-- provider's application name, used for tracing dependency relationship -->
	<dubbo:application name="dubbo-provider" />
	<!-- use multicast registry center to export service -->
	<dubbo:registry address="multicast://224.5.6.7:1234" />
	<!-- use dubbo protocol to export service on port 20880 -->
	<dubbo:protocol name="dubbo" port="20880" />
	<!-- service implementation, as same as regular local bean -->
	<bean id="helloService" class="top.guoj.provider.HelloServiceImpl" />
	<!-- declare the service interface to be exported -->
	<dubbo:service interface="top.guoj.api.HelloService"
		ref="helloService" />
</beans>
  • pom.xml
<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>top.guoj</groupId>
		<artifactId>dubbo-demo</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>top.guoj</groupId>
	<artifactId>dubbo-provider</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>dubbo-provider</name>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<version>2.6.2</version>
		</dependency>
		<dependency>
			<groupId>top.guoj</groupId>
			<artifactId>dubbo-api</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>
</project>

dubbo-consumer

├─src
│  ├─main
│  │  ├─java
│  │  │  └─top
│  │  │      └─guoj
│  │  │          └─consumer
│  │  └─resources
│  └─test
│      ├─java
│      └─resources
└─target
    ├─classes
    └─test-classes
  • Consumer.java
package top.guoj.consumer;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import top.guoj.api.HelloService;

public class Consumer {
	public static void main(String[] args) throws Exception {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				new String[] { "consumer.xml" });
		context.start();
		// Obtaining a remote service proxy
		HelloService demoService = (HelloService) context.getBean("helloService");
		// Executing remote methods
		String hello = demoService.sayHello("world");
		// Display the call result
		System.out.println(hello);
	}
}
  • consumer.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

	<!-- consumer's application name, used for tracing dependency relationship 
		(not a matching criterion), don't set it same as provider -->
	<dubbo:application name="dubbo-consumer" />
	<!-- use multicast registry center to discover service -->
	<dubbo:registry address="multicast://224.5.6.7:1234" />
	<!-- generate proxy for the remote service, then demoService can be used 
		in the same way as the local regular interface -->
	<dubbo:reference id="helloService" check="false"
		interface="top.guoj.api.HelloService" />
</beans>
  • pom.xml
<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>top.guoj</groupId>
		<artifactId>dubbo-demo</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>top.guoj</groupId>
	<artifactId>dubbo-consumer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>dubbo-consumer</name>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<version>2.6.2</version>
		</dependency>
		<dependency>
			<groupId>top.guoj</groupId>
			<artifactId>dubbo-api</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>
</project>

eclipse中搭建springboot helloword

安装sts(Spring Tools)

新建Spring Starter Project

项目结构如下:

application.yml

server:
  port: 8080</pre>

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>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

新建HelloController.java

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

	@RequestMapping(value = "/hello", method = RequestMethod.GET)
	public String HelloController() {
		return "Hello World!";
	}

}

运行Run As->Spring Boot App

Cesium之地形

Cesium支持对海洋,湖泊和河流的全球高分辨率地形和水影像进行流式传输和可视化。

支持多种地形provider来接收地形数据,大多数provider使用rest类型的接口来请求地形瓦片。

缺省情况下, 地球是一个 WGS84 椭球体。要添加Cesium的世界地形, 添加下面代码,珠穆朗玛峰显示如下:

viewer.terrainProvider = Cesium.createWorldTerrain();

Cesium世界地形还包括地形照明数据以及水效应所需的海岸线数据。默认情况下, 地形服务器不发送照明或海岸线数据与地形瓦片。在构造 CesiumTerrainProvider 时, 要启用地形照明, 从地形服务器请求 VertexNormals 扩展, 并启用全球照明。开启照明后珠穆朗玛峰显示如下:

var terrainProvider = Cesium.createWorldTerrain({
    requestVertexNormals: true
});
viewer.terrainProvider = terrainProvider;
viewer.scene.globe.enableLighting = true;

从地形服务器请求WaterMask扩展,开启水波效果:

var terrainProvider = Cesium.createWorldTerrain({
    requestWaterMask: true
});
viewer.terrainProvider = terrainProvider;

类型 说明 详情
Cesium World Terrain 高分辨率世界各地的地形, 支持地形照明和水影响的延伸。使用开放的运行时格式、量化网格 v1.0 将地形瓦片传递给客户端。 CesiumTerrainProvider
Google Earth Enterprise 从高度地图产生地形。 GoogleEarthEnterpriseTerrainProvider
VT MAK VR-TheWorld Server 从VR-TheWorld服务器中请求的高度地图生成地形。他们的托管服务器有90米的间距为整个地球, 包括水深。 VRTheWorldTerrainProvider
Ellipsoid 创建光滑表面的椭球体。这缺乏地形的真实外观, 但不请求服务器的数据, 对许多应用程序 (如空间) 非常有用。 EllipsoidTerrainProvider

可以通过TerrainProvider接口访问其它地形服务。要使用地形服务提供者,通过Viewer.terrainProvider来设置。

Cesium之图像图层

Cesium支持从多种标准服务中绘制和分层高分辨率图像。层可以单独, 并混合在一起。每个层的亮度、对比度、伽玛、色相和饱和度都可以动态改变。

首先通过imageryProvider使用Esri ArcGIS MapServer中的图层:

var viewer = new Cesium.Viewer('cesiumContainer', {
    imageryProvider : new Cesium.ArcGisMapServerImageryProvider({
        url : '//services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
    }),
    baseLayerPicker : false
});

添加另一个图层:使用NASA Black Marble imagery的 Tile Map Service (TMS):

var layers = viewer.scene.imageryLayers;
var blackMarble = layers.addImageryProvider(new Cesium.createTileMapServiceImageryProvider({
    url : '//cesiumjs.org/tilesets/imagery/blackmarble',
    maximumLevel : 8,
    credit : 'Black Marble imagery courtesy NASA Earth Observatory'
}));

后添加的NASA层覆盖了先添加的Esri层,可以通过blackMarble.alpha使二者融合。

blackMarble.alpha = 0.5; // 0.0 is transparent.  1.0 is opaque.

增加brightness灯光的亮度:

blackMarble.brightness = 2.0; // > 1.0 increases brightness.  < 1.0 decreases.

Imagery Provider使用特定服务发出图块的请求,Layer代表图像提供者显示的图块。

var layer = new ImageryLayer(imageryProvider);
layers.add(layer);

图层根据添加的顺序,从下到上绘制。一个像layers的图层集合,可以对图层集合中的图层进行操作add、romove、raise等。详情参见:ImgeryLayerCollection

Cesium之绘制图形

首先通过viewer.entities.add创建了一个entity(坐标定位在北京,根据坐标绘制了一个多边形),然后通过zoomto确保entity在视图中。

var viewer = new Cesium.Viewer('cesiumContainer');
var beijing = viewer.entities.add({
  name: 'Beijing',
  polygon: {
    hierarchy: Cesium.Cartesian3.fromDegreesArray([
      116.4, 39.9,
      116.38, 39.9,
      116.37, 39.92]),
    height: 0,
    material: Cesium.Color.RED.withAlpha(0.5),
    outline: true,
    outlineColor: Cesium.Color.BLACK
  }
});
viewer.zoomTo(beijing);

运行上面的代码,效果如下:

下面代码,将多边形高度提升到了地球20万米上空。

beijing.polygon.height = 200000;

如果height为undefined,则体积从0开始,下面代码创建从20万米开始并延伸到25万米,就意味着体本身达到5万米。

beijing.polygon.height = 200000;
beijing.polygon.extrudedHeight = 250000;

除了多边形,还有下面这些形状的实体:

实体 类型
Boxes entity.box
Circles entity.ellipse
Corridor entity.corridor
Cylinder entity.cylinder
Polygons entity.polygon
Polylines entity.polyline
Polyline Volumes entity.polylineVolume
Rectangles entity.rectangle
Spheres entity.ellipsoid
Walls entity.wall

下面代码分别在北京、上海、西安绘制3钟不同的实体图形:

var viewer = new Cesium.Viewer('cesiumContainer');
//北京
var greenCylinder = viewer.entities.add({
    name : '北京',
    position: Cesium.Cartesian3.fromDegrees(115.97, 40.45, 200000.0),
    cylinder : {
        length : 400000.0,
        topRadius : 200000.0,
        bottomRadius : 200000.0,
        material : Cesium.Color.GREEN.withAlpha(0.5),
        outline : true,
        outlineColor : Cesium.Color.DARK_GREEN
    }
});
// 上海
var redCone = viewer.entities.add({
    name : '上海',
    position: Cesium.Cartesian3.fromDegrees(121.47, 31.23, 200000.0),
    cylinder : {
        length : 400000.0,
        topRadius : 0.0,
        bottomRadius : 200000.0,
        material : Cesium.Color.RED
    }
});
//西安
var redBox = viewer.entities.add({
    name : '西安',
    position: Cesium.Cartesian3.fromDegrees(108.93, 34.343, 300000.0),
    box : {
        dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),
        material : Cesium.Color.RED.withAlpha(0.5),
        outline : true,
        outlineColor : Cesium.Color.BLACK
    }
});
viewer.zoomTo(viewer.entities);

效果如下图: