接口包含bean对象,service接口
例如
包含接口的实现类,不包含接口,接口写在公共API中
接口和Bean对象的引入在pom.xml中引入实现
<dependency>
<groupId>com.atguigu.gmallgroupId>
<artifactId>gmall-interfaceartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
引入dubbo依赖
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
<version>2.6.2version>
dependency>
编写provider.xml
<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="userserviceprovider">dubbo:application>
<dubbo:registry address="zookeeper://127.0.0.1:2181">dubbo:registry>
<dubbo:registry protocol="zookeeper" address="127.0.0.1:2181">dubbo:registry>
<dubbo:protocol name="dubbo" port="20880">dubbo:protocol>
<dubbo:service interface="com.atguigu.gmall.service.UserService"
ref="userServiceImpl">dubbo:service>
<bean id="userServiceImpl" class="com.atguigu.gmall.service.impl.UserServiceImpl">bean>
beans>
实现类无需做改动,正常完成
public class UserServiceImpl implements UserService {
public List<UserAddress> getUserAddressList(String userId) {
System.out.println("UserServiceImpl.....old...");
// TODO Auto-generated method stub
UserAddress address1 = new UserAddress(1, "北京市昌平区宏福科技园综合楼3层", "1", "李老师", "010-56253825", "Y");
UserAddress address2 = new UserAddress(2, "深圳市宝安区西部硅谷大厦B座3层(深圳分校)", "1", "王老师", "010-56253825", "N");
/*try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
return Arrays.asList(address1,address2);
}
}
包含接口的实现类,不包含接口,接口写在公共的API中
接口和Bean对象的引入在pom.xml中引入实现
<dependency>
<groupId>com.atguigu.gmallgroupId>
<artifactId>gmall-interfaceartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
<version>2.6.2version>
dependency>
编写consumer.xml
<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"
xmlns:context="http://www.springframework.org/schema/context"
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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.atguigu.gmall.service.impl">context:component-scan>
<dubbo:application name="userserviceprovider">dubbo:application>
<dubbo:registry address="zookeeper://127.0.0.1:2181">dubbo:registry>
<dubbo:reference interface="com.atguigu.gmall.service.UserService"
id="userService" check="false">
dubbo:reference>
beans>
实现类
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
UserService userService;
public List<UserAddress> initOrder(String userId) {
System.out.println("用户id,"+userId);
// 1、查询用户的收货地址
List<UserAddress> addressList = userService.getUserAddressList(userId);
return addressList;
}
}
github网址:https://github.com/apache/dubbo-spring-boot-project
UserAddress
public class UserAddress implements Serializable {
private Integer id;
private String userAddress; //用户地址
private String userId; //用户id
private String consignee; //收货人
private String phoneNum; //电话号码
private String isDefault; //是否为默认地址 Y-是 N-否
public UserAddress() {
super();
// TODO Auto-generated constructor stub
}
public UserAddress(Integer id, String userAddress, String userId, String consignee, String phoneNum,
String isDefault) {
super();
this.id = id;
this.userAddress = userAddress;
this.userId = userId;
this.consignee = consignee;
this.phoneNum = phoneNum;
this.isDefault = isDefault;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getConsignee() {
return consignee;
}
public void setConsignee(String consignee) {
this.consignee = consignee;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public String getIsDefault() {
return isDefault;
}
public void setIsDefault(String isDefault) {
this.isDefault = isDefault;
}
}
OrderService
public interface OrderService {
public List<UserAddress> initOrder(String userId);
}
UserService
public interface UserService {
/**
* 按照用户id返回所有的收货地址
* @param userId
* @return
*/
public List<UserAddress> getUserAddressList(String userId);
}
pom.xml
<dependency>
<groupId>org.apache.dubbogroupId>
<artifactId>dubbo-spring-boot-starterartifactId>
<version>2.7.8version>
dependency>
<dependency>
<groupId>com.atguigu.gmallgroupId>
<artifactId>gmall-interfaceartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
application.properties
dubbo.application.name=user-service-provider
dubbo.registry.address=127.0.0.1:2181
dubbo.registry.protocol=zookeeper
dubbo.protocol.name=dubbo
dubbo.protocol.port=20881
dubbo.monitor.protocol=registry
实现类
@DubboService注解的作用:暴露服务,这样就不用在xml文件中配置。
@DubboService
@Service
public class UserServiceImpl implements UserService {
public List<UserAddress> getUserAddressList(String userId) {
System.out.println("UserServiceImpl.....old...");
// TODO Auto-generated method stub
UserAddress address1 = new UserAddress(1, "北京市昌平区宏福科技园综合楼3层", "1", "李老师", "010-56253825", "Y");
UserAddress address2 = new UserAddress(2, "深圳市宝安区西部硅谷大厦B座3层(深圳分校)", "1", "王老师", "010-56253825", "N");
return Arrays.asList(address1,address2);
}
}
springboot主程序
@EnableDubbo注解的作用:开启基于注解的dubbo功能
@EnableDubbo //开启基于注解的dubbo功能
@SpringBootApplication
public class BootUserServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(BootUserServiceProviderApplication.class, args);
}
}
springboot勾选spring web,导入web相关的依赖
<dependency>
<groupId>com.atguigu.gmallgroupId>
<artifactId>gmall-interfaceartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.apache.dubbogroupId>
<artifactId>dubbo-spring-boot-starterartifactId>
<version>2.7.8version>
dependency>
application.properties
server.port=8081
dubbo.application.name=consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.monitor.protocol=registry
实现类
@DubboReference注解的作用:引用服务
@Service
public class OrderServiceImpl implements OrderService {
//@Autowired
@DubboReference
UserService userService;
public List<UserAddress> initOrder(String userId) {
System.out.println("用户id,"+userId);
// 1、查询用户的收货地址
List<UserAddress> addressList = userService.getUserAddressList(userId);
return addressList;
}
}
控制器
@Controller
public class OderController {
@Autowired
OrderService orderService;
@ResponseBody
@RequestMapping("/initOrder")
public List<UserAddress> initOrder(@RequestParam("uid")String userId){
return orderService.initOrder(userId);
}
}
springboot主程序
@EnableDubbo
@SpringBootApplication
public class BootOrderServiceConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(BootOrderServiceConsumerApplication.class, args);
}
}
支持
面向接口代理的高性能RPC调用
只能负载均衡
服务自动注册与发现
高度可拓展能力
运行流量调度
可视化的服务治理和运维
工作原理
第一次启动会缺少zoo.config
需要将zoo_sample.cfg复制一份改名为zoo.cfg
打开zoo.cfg 修改配置
打开zkServer
启动成功
启动zkCli服务器
前提: 打开zookeeper
进入dubbo github网站
https://github.com/apache/dubbo
切换至master-0.2.0
检查该文件中resources目录下的application.properties文件的配置
相同的话,跳到dubbo-admin文件夹目录,在该页面打开cmd ,mvn clean package生成target文件
放在自己想放的目录下,并在该目录下使用cmd命令行运行
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
浏览器打开localhost:7001
登录账号 root 密码 root
dubbo 2.6是jar包 25.以前是war包
UserService 比较常用,总不能一直把UserService和bean放到别的module中,所以分包
为了使得orderservice调用方法,使用dubbo改造
springboot 暴露服务
用注解来配置
@DubboService 暴露服务
主程序中开启 @EnableDubbo
启动的时候出现了错误,提示缺少包,加入依赖
中间也因为加入依赖等级太高而失败,注意zoo版本和这个的匹配
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-frameworkartifactId>
<version>2.12.0version>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-recipesartifactId>
<version>2.12.0version>
dependency>
使用接口用使用注解的方式
@DubboReference
三大步
1、导入dubbo
2、application.properties中写入dubbo配置
3、暴露服务使用 @DubboService注解 消费服务使用@Reference注入
1、配置优先级
公共的配置 dubbo.properties
2、启动检查
官方文档:https://dubbo.apache.org/zh/docs/advanced/preflight-check/
正常情况下,当注册中心没有提供者时,启动消费者,消费者程序就会报错。
启动检查便是来解决这个问题的。
示例:
在xml文件中设置false,为一种服务配置
配置所有的服务都不检查
dubbo:consumer的其他配置
官方文档:https://dubbo.apache.org/zh/docs/references/xml/dubbo-consumer/
主程序
package com.atguigu.gmall;
import com.atguigu.gmall.service.OrderService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class MainApplication {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("consumer.xml");
System.out.println("调用完成");
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果为 调用完成
如果不设置check=false ,则报错
设置check=false的方式
springboot中 @DubboReference(version = 1.0.0 , check = false)
3、超时&配置覆盖关系
解决问题:消费方使用提供方的方法,可能提供方的方法要使用很长时间,如果很长时间都没返回,导致大量线程阻塞,会引起性能下降
可以指定超时属性,如果没有反应,就立即终止,不让线程阻塞
超时说明
消费者配置超时
配置优先级
xml配置官方文档:https://dubbo.apache.org/zh/docs/references/configuration/xml/
消费者方法 > 提供者方法 > 消费者接口 > 提供者接口 > 消费者全局 > 提供者全局
4、重试次数
说明
retries=“”,重试次数,不包含第一次调用,0代表不重试
原则
幂等函数设置重试次数【查询、删除、修改,即每次运行都是相同的效果】
非幂等函数不能设置重置次数【新增】
多个提供方
当有多个提供方提供相同的功能的时候,如果重试失败,会换下一次提供方,默认时轮询
5、多版本
官方文档:https://dubbo.apache.org/zh/docs/advanced/multi-versions/
作用
实现灰度发布
实现方式
提供方写多个实现类,并配置版本号
提供方
版本1配置
版本2配置
消费方
调用版本1 version=“1.0.0”
调用版本2 version=“2.0.0”
随机调用版本 *
6、本地存根
官方文档:https://dubbo.apache.org/zh/docs/advanced/local-stub/
7、与Springboot整合的三种方式
1)、导入dubbo-starter,在application.properties配置属性,使用@Service【暴露服务】使用@Reference【引用服务】
前提:开启注解的dubbo功能
1、在启动程序中写@EnableDubbo
2、或者在配置中写 dubbo.scan.base-packages=com.atguigu.gmall
2)、保留dubbo xml配置文件
方法:
导入dubbo-starter。使用@ImportResource导入dubbo配置文件即可
目的:
3)使用注解API的方式
将每一个组件手动创建到容器中
API配置官方文档:https://dubbo.apache.org/zh/docs/references/configuration/api/
注解配置官方文档:https://dubbo.apache.org/zh/docs/references/configuration/annotation/
(建议看API文档
高可用:通过设计,减少系统不能提供服务的时间
问题:
1)zookeeper宕机了,消费者还能不能调用服务提供者?
能,因为有本地缓存保持通讯
2)没有zookeeper,可以调用服务提供者吗?
可以,dubbo可以直连服务提供者
官方文档:https://dubbo.apache.org/zh/docs/advanced/loadbalance/
缺省为 random
随机调用
1)基于权重的随即负载均衡机制
根据权重值得到每个Provider的概率,进行有概率的调用
2)基于权重的轮询负载均衡机制
根据权重,分配每个provider的概率,并通过轮询的方式科学地实现概率
3)最少活跃数-负载均衡机制
根据上一次provider的反应速度,选择最快的provider
4)一致性hash-负载均衡机制
根据哈希结果进入,
消费端设置
轮询机制配置
加权轮询配置
消费者 @Reference(loadbalance=“random”)
1) 静态设置 在提供者注解中设置@Service(weight= “”)
2) 动态设置 在控制台
当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。
可以通过服务降级功能临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。
在消费者配置
屏蔽:消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。
容错:消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。
集群容错文档:https://dubbo.apache.org/zh/docs/advanced/fault-tolerent-strategy/
缺省为 failover 重试
整合hystrix
针对 消费者 和 提供者
spring boot官方提供了对hystrix的集成,直接在pom.xml里加入依赖:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId> <version>1.4.4.RELEASEversion>
dependency>
然后在Application类上增加@EnableHystrix来启用hystrix starter:
@SpringBootApplication
@EnableHystrix
public class ProviderApplication {
在Dubbo的Provider上增加@HystrixCommand配置,这样子调用就会经过Hystrix代理。
@Service(version = "1.0.0")
public class HelloServiceImpl implements HelloService {
@HystrixCommand(commandProperties =
{@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
@HystrixProperty(name ="execution.isolation.thread.timeoutInMilliseconds", value = "2000") })
@Override
public String sayHello(String name)
{ // System.out.println("async provider received: " + name);
// return "annotation: hello, " + name;
throw new RuntimeException("Exception to show hystrix enabled.");
}
}
对于Consumer端,则可以增加一层method调用,并在method上配置@HystrixCommand。当调用出错时,会走到fallbackMethod = "reliable"的调用里。
@Reference(version = "1.0.0")
private HelloService demoService;
@HystrixCommand(fallbackMethod = "reliable")
public String doSayHello(String name) {
return demoService.sayHello(name); }
public String reliable(String name)
{ return "hystrix fallback value";}
待补充…