Dubbo:阿里巴巴的开源,高性能,轻量级的java RPC框架,提供了三大核心能力
1.面向接口的远程方法调用
2.只能容错和负载均衡
3.服务自动注册和发现
分层结构说明
1.应用层:距离用户最近的一层,接入层,接受用户请求
2.业务服务层:更具具体的业务场景,演变而来的模块
3.基础服务层:通用服务
4.存储层:mysql,Mongodb ES fastDFS
优点:
服务已接口为粒度,为开发者屏蔽远程调用底层细节
业务分层以后架构更加清晰,并且每个业务模块职责单一,拓展性更强
数据隔离,权限回收,数据访问都通过接口,让系统更加稳定
服务应用本身无状态化 本身不做内存级缓存,而是把数据直接存入db
服务责任易确定
缺点:
粒度控制复杂 如果没有控制好服务的粒度,模块越来越多,会引发超时 分布式事务等问题
服务接口数量不宜控制,容易造成接口爆炸
版本升级兼容困难
调用链路长
微服务架构
强调业务需要彻底的组件化和服务化
Dubbo处理流程
服务提供者在服务容器启动时 向注册中心 注册自己提供的服务
服务消费者在启动时 向注册中心订购自己所需要的服务
注册中心返回服务提供者地址列表给消费者
服务消费者 从提供者地址中 基于软负载均衡算法 选一台提供者进行调研
服务提供者和消费者 在内存中调用次数和时间美每分钟发送空着中心
服务注册中心zookeeper
提供者提供实现类并且注册到中心上
调用者只需引入该接口
Dubbo实战
1.建立maven功能,创建API模块,用于规范双方接口协定
2.提供privider模块,引入API接口,并实现对应的接口
3.提供consumer模块,引入API模块,引入与提供者相同的注册中心,在进行服务调用
Dubbo配置的几种方法:
1.使用注解,但这种方法有一个弊端:有些时候配置信息并不是特别好找,无法快速定位
2.XML:一般是和spring做结合,可以通过几个文件就可以管理整个集群,可以快速定位
3.基于代码方法
Dubbo 管理控制台 dubbo-admin
作用:服务管理,路由规则,权重调整等管理功能
部署方式:在git上下载项目,修改项目对应的配置,部署服务器,运行
Dubbo配置项说明:
dubbo:application
1.name:当前应用程序的名称
2.owner:当前应用程序的负责人
3.qosEnable:是否启动QoS,默认true
4.qosPort:启动Qos绑定的端口 默认22222
5.qosAcceptForeignip:是否允许远程访问 默认是false
dubbo:registry
代表该模块使用的注册中心 一个模块的服务可以将其注册到多个注册中心,也可以注册到一个上
dubbo:protocol
指定服务在进行数据传输所使用的协议
dubbo:service
指定当前需要对外暴露的服务信息
dubbo:reference
消费者的配置
dubbo:method
针对某个具体方法的特殊处理
详解:dubbo:service和dubbo:reference
mock:用于在方法调用出现错误时,当做服务降级来统一对外返回结果
timeout:用于指定当前方法或者接口中所有方法的超时时间
check:用于在启动时,检测生产则是否有该服务。
retries:用于指定当前服务在执行时出现错误或超时的重试机制
executes:用于在提供者做配置,来确保最大的并行度
快速搭建一个dubbo项目(注解类)
分为三个模块
api模块需要实现的接口
public interface HelloService {
String sayHello(String name);
}
consumer模块中HelloServiceMock是当程序出现后的降级方法实现
public class HelloServiceMock implements HelloService{
@Override
public String sayHello(String name) {
return "hello mock";
}
}
dubbo-consumer.xml中需要注意的如果qos.port没有设置,那么会走默认的22222,与provider冲突,会报端口被占用的错误
<?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://dubbo.apache.org/schema/dubbo"
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="service-consumer">
<dubbo:parameter key="qos.enable" value="true"/>
<dubbo:parameter key="qos.port" value="33333"/>
<dubbo:parameter key="qos.accept.foreign.ip" value="true"/>
</dubbo:application>
<dubbo:registry address="zookeeper://ip:2181"/>
<dubbo:reference id="helloService" interface="com.test.service.HelloService" version="1.0"/>
</beans>
consumer主方法
public class XMLConsumerMain {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:dubbo-consumer.xml");
// context.start();
HelloService bean = context.getBean("helloService",HelloService.class);
System.in.read();
System.out.println(bean.sayHello("dadada"));
}
}
以下为provider模块
有接口的实现方法
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return "hello " + name;
}
}
注解相关的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://dubbo.apache.org/schema/dubbo"
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-provider"/>
<dubbo:registry address="zookeeper://ip:2181"/>
<dubbo:protocol name="dubbo" port="20883"/>
<bean id="helloService" class="com.test.service.impl.HelloServiceImpl"/>
<dubbo:service interface="com.test.service.HelloService" ref="helloService" version="1.0"/>
</beans>
主方法
public class ProviderApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:dubbo-provider.xml");
context.start();
System.in.read();
}
}
pom文件
<?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>dubbo-xml-test</groupId>
<artifactId>dubbo-xml-test</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>service-api</module>
<module>service-provider</module>
<module>service-consumer</module>
</modules>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.5</version>
<exclusions>
<exclusion>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
<version>2.7.5</version>
<exclusions>
<exclusion>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-dubbo</artifactId>
<version>2.7.5</version>
<exclusions>
<exclusion>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-remoting-netty4 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-netty4</artifactId>
<version>2.7.5</version>
<exclusions>
<exclusion>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-serialization-hessian2 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-hessian2</artifactId>
<version>2.7.5</version>
<exclusions>
<exclusion>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 日志配置 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<!-- json数据化转换 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
要有 <exclusions>,否则会出error log,提示两个jar包中有相同名字的类
运行结果
SPI:是JDK内置的一种服务提供发现机制
SPI遵守的约定
1.当服务提供者提供了接口的一种实现后,在META-INF/services目录下创建一个以"接口全限定名"为命名的文件,内容为实现类的全限定名
2.接口实现类所在的jar包放在主程序的classpath中
3.主程序通过java.util.ServiceLoader动态装载实现模块,通过扫描META-INF/services目录的配置文件找到实现类的全限定名,把类加载到JVM
4.SPI的实现类必须携带一个无参构造方法
Dubbo中的SPI
可以实现自己的实现类