1.下载地址和文档
dubbo 文档和配置说明地址:
http://dubbo.apache.org/zh-cn/docs/user/references/xml/dubbo-config-center.html
dubbo 已经捐赠给 Apache 了, github 地址:
https://github.com/apache/dubbo-spring-boot-project
zookeeper下载地址:http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.5.5/
很多人在学习一个新的技术或者是不懂的技术的时候,最头疼的就是想知道如果配置,有哪些配置,配置的作用是什么
我建议是可以先看看 这个 dubbo 的配置,字段说明都很详细,对应是XML 或者是 注解模式配置都是通用的
zookeeper 下载这个 bin文件
2. 安装ZOOKEEPER
这个安装其实没什么好说的,解压,配置一下,就可以直接使用了
我安装的是 3.5.5 版本的zookeeper,这个版本多了一个新的功能,就是 AdminServer,默认是需要占用 8080 端口的,如果机器上8080端口已经被占用了,会导致安装给不成功。
解压之后 重命名zoo_sample.conf 为 zoo.cfg
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/tmp/zookeeper
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
# 这个配置是修改默认的 adminServer的启动端口的
admin.serverPort=8081
我没有安装集群的 zookeeper 所以这样配置就没有问题了
如果想要集群模式的 zookeeper,
## if you have many server 多服务集群模式 后面的3888端口是 提供服务端口
#server.1=192.168.23.200:2888:3888
#server.2=192.168.23.211:2888:3888
#server.3=192.168.23.212:2888:3888
server.1=192.168.23.200:2888:3888
server.A=B:C:D:其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。
配置好了之后就启动。
cd /bin ./zkServer.sh start 启动
查看状态
./zkServer.sh status
./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/zookeeper-3.5.5/bin/../conf/zoo.cfg
Mode: standalone
[root@localhost bin]#
standalone 标识单机模式
3. github 仓库
在github里面有这个样例工程,建议第一次使用的同学,去下载下来看看这个工程里面的配置,还是很清晰的
里面有提供,直连模式,注册中心模式,2种模式的使用方式
4. springboot2
开始说说代码部分
dubbbo的使用,肯定是有一个公共依赖的接口层(这也是dubbo 一个我任务比较重的地方)
a. 公共依赖JAR包
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.smk.dubbo</groupId>
<artifactId>cat_dubbo_api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cat_dubbo_api</name>
<description>cat_dubbo_api</description>
<packaging>jar</packaging>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<build>
<finalName>cat_dubbo_api</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
接口类
package com.smk.service;
public interface NameService {
String getNameByType(String type);
}
b. 服务提供者
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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.smk.dubbo</groupId>
<artifactId>cat_dubbo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cat_dubbo_provider</name>
<description>cat_dubbo_provider</description>
<packaging>jar</packaging>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.9.RELEASE</version>
</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>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.1</version>
</dependency>
<!-- 依赖的公共API接口包-->
<dependency>
<groupId>com.smk.dubbo</groupId>
<artifactId>cat_dubbo_api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--zookeeper 依赖包-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.1</version>
<type>pom</type>
</dependency>
</dependencies>
<build>
<finalName>cat_dubbo_provider</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.application.index=true
spring.application.name=cat_dubbo
spring.jmx.default-domain=cat_dubbo
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.default-property-inclusion=non_null
spring.jackson.time-zone=GMT+8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
home.path=classpath:config
#home.path=/usr/local/tomcat/tomcat8081_smk_mall/config
logging.config=${home.path}/logback-spring.xml
logging.level.com=debug
server.port=8081
# the servlet path, defaults to '/'
server.servlet.context-path=/cat_dubbo
# session timeout in seconds
server.session.timeout=30*60
server.tomcat.uri-encoding=UTF-8
server.connection-timeout=20000
server.tomcat.accept-count=800
server.tomcat.max-connections=500
server.tomcat.max-threads=1000
#dubbo.application.name=mydubboservice
#dubbo.application.id=mydubboservice
#dubbo.protocol.id=dubbo
#dubbo.protocol.name=dubbo
#dubbo.protocol.port=20880
#上面注释的都是可以使用默认值的,需要修改才需要配置
#扫描注解的包名
dubbo.scan.base-packages=com.smk.dubbo.service.impl
#注册中心地址。直连模式不需要
dubbo.registry.address=zookeeper://192.168.23.212:2181
service
import org.apache.dubbo.config.annotation.Service;
import com.smk.service.NameService;
//注意这个service的包名,是dubbo的,不是spring的
@Service()
public class NameServiceImpl implements NameService {
@Override
public String getNameByType(String type) {
return "server:"+type;
}
}
这里大致看一下 这个注解的代码说明
...........
/**
* Service annotation
*
* @export
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Inherited
public @interface Service {
/**
* Interface class, default value is void.class
*/
Class<?> interfaceClass() default void.class;
/**
* 存在多个实现类的时候需要写上去
* Interface class name, default value is empty string
*/
String interfaceName() default "";
/**
在区别版本的时候,调用方可以更具版本号 区别调用
* Service version, default value is empty string
*/
String version() default "";
/**
* 如果使用同一個zookeeper环境,想要区分测试环境的 服务和 生产环境的服务,这个group就有作用了
* Service group, default value is empty string
*/
String group() default "";
/**
* Service path, default value is empty string
*/
String path() default "";
/**
* Whether to export service, default value is true
*/
boolean export() default true;
/**
* Service token, default value is false
*/
String token() default "";
/**
* Whether the service is deprecated, default value is false
*/
boolean deprecated() default false;
/**
* Whether the service is dynamic, default value is false
*/
boolean dynamic() default false;
/**
* Access log for the service, default value is ""
*/
String accesslog() default "";
/**
* Maximum concurrent executes for the service, default value is 0 - no limits
*/
int executes() default 0;
/**
* Whether to register the service to register center, default value is true
*/
boolean register() default true;
/**
* Service weight value, default value is 0
*/
int weight() default 0;
/**
* Service doc, default value is ""
*/
String document() default "";
/**
* Delay time for service registration, default value is 0
*/
int delay() default 0;
/**
* @see Service#stub()
* @deprecated
*/
String local() default "";
/**
* Service stub name, use interface name + Local if not set
*/
String stub() default "";
/**
* Cluster strategy, legal values include: failover, failfast, failsafe, failback, forking
*/
String cluster() default "";
/**
* How the proxy is generated, legal values include: jdk, javassist
*/
String proxy() default "";
/**
* Maximum connections service provider can accept, default value is 0 - connection is shared
*/
int connections() default 0;
/**
* The callback instance limit peer connection
*
* @see Constants#DEFAULT_CALLBACK_INSTANCES
*/
int callbacks() default Constants.DEFAULT_CALLBACK_INSTANCES;
/**
* Callback method name when connected, default value is empty string
*/
String onconnect() default "";
/**
* Callback method name when disconnected, default value is empty string
*/
String ondisconnect() default "";
/**
* Service owner, default value is empty string
*/
String owner() default "";
/**
* Service layer, default value is empty string
*/
String layer() default "";
/**
* Service invocation retry times
*
* @see Constants#DEFAULT_RETRIES
*/
int retries() default Constants.DEFAULT_RETRIES;
/**
* Load balance strategy, legal values include: random, roundrobin, leastactive
*
* @see Constants#DEFAULT_LOADBALANCE
*/
String loadbalance() default Constants.DEFAULT_LOADBALANCE;
/**
* Whether to enable async invocation, default value is false
*/
boolean async() default false;
/**
* Maximum active requests allowed, default value is 0
*/
int actives() default 0;
/**
* Whether the async request has already been sent, the default value is false
*/
boolean sent() default false;
/**
* Service mock name, use interface name + Mock if not set
*/
String mock() default "";
/**
* Whether to use JSR303 validation, legal values are: true, false
*/
String validation() default "";
/**
* Timeout value for service invocation, default value is 0
*/
int timeout() default 0;
/**
* Specify cache implementation for service invocation, legal values include: lru, threadlocal, jcache
*/
String cache() default "";
/**
* Filters for service invocation
*
* @see Filter
*/
String[] filter() default {};
/**
* Listeners for service exporting and unexporting
*
* @see ExporterListener
*/
String[] listener() default {};
/**
* Customized parameter key-value pair, for example: {key1, value1, key2, value2}
*/
String[] parameters() default {};
/**
* Application spring bean name
*/
String application() default "";
/**
* Module spring bean name
*/
String module() default "";
/**
* Provider spring bean name
*/
String provider() default "";
/**
* Protocol spring bean names
*/
String[] protocol() default {};
/**
* Monitor spring bean name
*/
String monitor() default "";
/**
* Registry spring bean name
*/
String[] registry() default {};
/**
* Service tag name
*/
String tag() default "";
/**
* methods support
* @return
*/
Method[] methods() default {};
}
启动类
package com;
import java.io.IOException;
import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@Configuration
@EnableAsync
@EnableScheduling
@EnableCaching
@EnableAutoConfiguration()
// 开启dubbo 配置
@EnableDubboConfig
public class App {
public static void main(String[] args) throws IOException {
SpringApplication.run(App.class, args);
}
}
c 服务消费者
消费者的所有配置基本和服务提供者保持一致。
消费者消费 dubbo的服务可以分2种,一种是直连 对方服务(服务提供者可以配置禁用这种方式),第二种是通过注册中心获取
直连方式
package com.smk.action;
import java.util.HashMap;
import java.util.Map;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.smk.service.NameService;
@RequestMapping("dubbo")
@RestController
@Scope("prototype")
public class GetNameAction {
//直连方式需要指定 url
@Reference(url="dubbo://localhost:20880")
private NameService nameService;
/**
* 保存/更新
*/
@RequestMapping("{code}")
public Object doSave(@PathVariable("code") String code) {
String name = nameService.getNameByType(code);
Map<String, Object> m = new HashMap<String, Object>();
m.put("name", name);
return m;
}
}
注册中心模式
删除掉 url配置即可
同时配置文件中,需要指定注册中心的地址
dubbo.registry.address=zookeeper://192.168.23.212:2181
互相调用问题
在实际生产环境中个,dubbo中的每个服务,都可能 即是服务提供者,也是服务消费者。有一种情况是,A,B 2个服务互相调用,A调用B 的服务,B 调用A 的服务
按照普通的方式,这样是不能成功的,需要做一些额外的配置
@Reference(check = false)
private NameService nameService;
需要再Reference 中 设置 check 为 false.
且,提供的服务中,不能直接调用别的服务
dubbo 精彩的点
-
可以实现异步方式调用
-
可以实现服务降级和熔断
使用MOCK服务支持,服务熔断和降级功能
-
多种协议支持,满足不同场景使用
dubbo协议,单一长连接,NIO异步通信,适合小数据,高并发,服务消费者多,提供者少 hessian协议,http通信,servlet暴露服务,适合数据量大,
-
同一个服务,可以对外提供多种协议支持
-
可以自定义线程池策略
-
提供负载均衡策略选择