dubbo-Filter、group、version使用

本文介绍了在Dubbo中如何使用Filter,详细步骤包括创建AuthorityFilter配置文件,并在服务上添加filter。此外,讨论了dubbo的version和group配置在接口重构时的作用,以及如何通过url配置进行本地测试。还提到了dubbo的cache功能,用于缓存热点数据以优化幂等请求。文章进一步解析了dubbo调用流程,包括服务注册、消费者拉取提供者列表及负载均衡策略。最后,简要提及了Dubbo的几种负载均衡方式,如随机、轮询、最小请求数和一致哈希。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、项目结构

服务提供方:


消费方:


提供者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>com.fox</groupId>
    <artifactId>dubbo-service</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.fox</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>1.0.0</version>
        </dependency>

        <!--  Spring Boot Dubbo 依赖-->
        <dependency>
            <groupId>io.dubbo.springboot</groupId>
            <artifactId>spring-boot-starter-dubbo</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.15</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>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

消费者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>com.fox</groupId>
    <artifactId>dubbo-consumer</artifactId>
    <version>1.0.0</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fox</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>1.0.0</version>
        </dependency>
        <!--  Spring Boot Dubbo 依赖-->
        <dependency>
            <groupId>io.dubbo.springboot</groupId>
            <artifactId>spring-boot-starter-dubbo</artifactId>
            <version>1.0.0</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.15</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>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

提供者properties

server.port=8081
#dubbo提供者的别名,只是个标识
spring.dubbo.application.name=provider
#zk地址
spring.dubbo.registry.address=zookeeper://172.16.10.15:2181
#dubbo协议
spring.dubbo.protocol.name=dubbo
#duboo端口号
spring.dubbo.protocol.port=20880
#这是你要发布到dubbo的接口所在包位置
spring.dubbo.scan=com.fox

消费者properties

server.port=8080
#dubbo提供者的别名,只是个标识
spring.dubbo.application.name=consumer-1
#zk地址
spring.dubbo.registry.address=zookeeper://172.16.10.15:2181
#dubbo协议
spring.dubbo.protocol.name=dubbo
#duboo端口号
spring.dubbo.protocol.port=20880
#这是你要发布到dubbo的接口所在包位置
spring.dubbo.scan=com.fox

一、Filter使用:

package com.fox.config;

import com.alibaba.dubbo.rpc.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;


public class AuthorityFilter implements Filter {
    private static final Logger LOGGER = LoggerFactory.getLogger(AuthorityFilter.class);
  
    private IpWhiteList ipWhiteList;  
  
    //dubbo通过setter方式自动注入  
    public void setIpWhiteList(IpWhiteList ipWhiteList) {  
        this.ipWhiteList = ipWhiteList;  
    }  
  
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        if (!ipWhiteList.isEnabled()) {  
            LOGGER.info("白名单禁用");
            return invoker.invoke(invocation);  
        }  
  
        String clientIp = RpcContext.getContext().getRemoteHost();  
        LOGGER.info("访问ip为{}", clientIp);
        List<String> allowedIps = ipWhiteList.getAllowedIps();
        if (allowedIps.contains(clientIp)) {  
            return invoker.invoke(invocation);  
        } else {  
            return new RpcResult();  
        }  
    }  
} 
package com.fox.config;

import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * dubbo白名单
 *
 * @author
 * @create 2018-04-11 10:38
 **/
@Component
public class IpWhiteList {

    //白名单是否禁用
    public Boolean isEnabled() {
        return true;
    }

    //白名单列表
    List<String> getAllowedIps() {
        List<String> whiteList = new ArrayList<>();
        whiteList.add("192.168.30.9");
        whiteList.add("192.168.20.1");
        return whiteList;
    }

}

在resources下添加com.fox.config.AuthorityFilter纯文本文件目录如上图,内容为

authorityFilter=com.fox.config.AuthorityFilter

最后在提供服务的service上添加filter

package com.fox.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.fox.api.ProviderApiService;
import com.fox.service.ProviderService;

import javax.annotation.Resource;

/**
 * Created by sh00859 on 2018/4/10.
 */
@Service(filter = "authorityFilter")
public class ProviderApiServiceImpl implements ProviderApiService {
    @Resource
    private ProviderService providerService;

    @Override
    public String queryDubboTestName(String name) {
        return providerService.queryDubboTestName(name);
    }
}

上述几个步骤实现了Filter的基础功能,在whiteList当中的ip可以访问,在访问时会根据消费者的ip自动找到相应可以访问的提供者服务

二、dubbo各种参数配置

当修改接口或者重构接口又不影响老接口使用时可以利用version和group来实现

    @Reference(group = "group1")
    private ProviderApiService providerApiService;
    @Reference(group = "group2")
    private ProviderApiService providerApiService2;

当本地测试需要连接指定主机时可配置url来实现直接RPC

    @Reference(url = "dubbo://192.168.20.8:20880")
    private ProviderApiService providerApiService;

对于热点数据可以开启dubbo的cache来缓存数据,对于幂等的请求会优先查询缓存结果

    @Reference(cache = "true")
    private ProviderApiService providerApiService;

三、dubbo调用流程

提供者启动服务时会将服务注册到注册中心,消费者启动服务时会从注册中心拉取提供者列表及相关策略(负载均衡)缓存到本地,调用时直接通过本地缓存的连接地址访问远程服务,当注册中心宕机后不影响正常调用,当提供者提供的服务或者策略发生变化并通知到注册中心时,注册中心会通知消费者重新缓存提供者的列表或者策略到本地

四、dubbo的负载均衡策略

随机、轮询、最小请求数、一致hash

RandomLoadBalance:

    protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        int length = invokers.size(); // 总个数
        int totalWeight = 0; // 总权重
        boolean sameWeight = true; // 权重是否都一样
        for (int i = 0; i < length; i++) {
            int weight = getWeight(invokers.get(i), invocation);
            totalWeight += weight; // 累计总权重
            if (sameWeight && i > 0
                    && weight != getWeight(invokers.get(i - 1), invocation)) {
                sameWeight = false; // 计算所有权重是否一样
            }
        }
        if (totalWeight > 0 && ! sameWeight) {
            // 如果权重不相同且权重大于0则按总权重数随机
            int offset = random.nextInt(totalWeight);
            // 并确定随机值落在哪个片断上
            for (int i = 0; i < length; i++) {
                offset -= getWeight(invokers.get(i), invocation);
                if (offset < 0) {
                    return invokers.get(i);
                }
            }
        }
        // 如果权重相同或权重为0则均等随机
        return invokers.get(random.nextInt(length));
    }



使用SpringBoot + Dubbo框架的项目中集成Seata,需要进行以下步骤: 1. 添加Seata的相关依赖 在项目的pom.xml文件中添加Seata的相关依赖: ```xml <dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> <version>${seata.version}</version> </dependency> ``` 2. 配置Seata的注册中心 在项目的application.properties或application.yml文件中添加Seata的注册中心配置,例如: ```yaml spring: cloud: alibaba: seata: tx-service-group: my_test_tx_group config: type: nacos nacos: server-addr: localhost:8848 namespace: seata registry: type: nacos nacos: server-addr: localhost:8848 application: seata-server ``` 其中,tx-service-group是Seata的事务组名称,config和registry是Seata的注册中心配置,这里使用的是Nacos作为注册中心,也可以使用其他的注册中心。 3. 配置Dubbo的Seata拦截器 在Dubbo的服务提供方和服务消费方中都需要添加Seata的拦截器,以实现分布式事务的管理。在SpringBoot + Dubbo框架中,可以通过配置文件或注解的方式来添加Seata的拦截器。 (1)配置文件方式 在Dubbo的服务提供方和服务消费方的application.properties或application.yml文件中添加Seata的拦截器配置,例如: ```yaml # 服务提供方 dubbo.provider.filter=seata # 服务消费方 dubbo.consumer.filter=seata ``` (2)注解方式 在Dubbo的服务提供方和服务消费方的实现类中,使用@DubboService和@DubboReference注解来定义Dubbo服务,同时在@DubboService和@DubboReference注解中添加filter属性来指定Seata的拦截器,例如: ```java // 服务提供方 @DubboService(version = "1.0.0", filter = {"seata"}) public class OrderServiceImpl implements OrderService { // ... } // 服务消费方 public class UserServiceImpl implements UserService { @DubboReference(version = "1.0.0", filter = {"seata"}) private OrderService orderService; // ... } ``` 4. 编写分布式事务代码 在Dubbo的服务提供方和服务消费方中,通过Seata提供的API来实现分布式事务的管理,例如: ```java // 服务提供方 @Service public class OrderServiceImpl implements OrderService { @Override @GlobalTransactional public void createOrder(Order order) { // 保存订单信息 orderMapper.insert(order); // 扣减库存 storageService.reduceStock(order.getProductId(), order.getCount()); // 扣减余额 accountService.reduceBalance(order.getUserId(), order.getMoney()); } } // 服务消费方 @Service public class UserServiceImpl implements UserService { @DubboReference(version = "1.0.0") private OrderService orderService; @Override @GlobalTransactional public void createUser(User user, Order order) { // 注册用户 userMapper.insert(user); // 创建订单 orderService.createOrder(order); } } ``` 在以上代码中,使用@GlobalTransactional注解来标记分布式事务的范围,Seata会根据这个注解来创建全局事务,并在所有涉及到的服务中进行事务的协调和管理。 综上所述,以上就是在SpringBoot + Dubbo框架中使用Seata进行分布式事务管理的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值