Dubbo & 负载均衡

hello world

1.启动Zookeeper

2.创建工程provider

1.导入依赖

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

        <!-- dubbo启动器 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>3.0.4</version>
        </dependency>
        <!-- apache 提供的zookeeper客户端访问框架 -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>5.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>5.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-x-discovery</artifactId>
            <version>5.1.0</version>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>dubboserver</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

2.yml配置

server:
  port: 8001
spring:
  application:
    name: student
# dubbo相关配置。
dubbo:
  application: # 注意:部分低版本dubbo中。dubbo.application.id必要。
    id: student # 可选配置,dubbo服务的唯一命名。默认${dubbo.application.name}
    name: student # 必要配置,dubbo服务的唯一命名。
  registry: # 配置注册中心地址。必要配置。
    address: zookeeper://127.0.0.1:32768  # 注册中心地址
    timeout: 300000  # 超时配置
  protocol: # dubbo的provider启动后,监听什么端口,处理什么协议。
    name: dubbo # dubbo协议。默认值。推荐使用。
    port: 20881 # provider监听的端口。默认值20880。

3.业务层代码
@Dubboservice,让开发时候只看service 即可
@Dubboservice是2.7.7才新增注解﹑之前@service和我们之前使用的@service是同名不同包作用:
1、创建当前类对象交给Spring容器进行管理和@service的作用是一样的
2、根据配置文件中配置的注册中心信息﹑连接注册中心完成内容注册

service:
public interface StudentService {
    
    
    String show();
}

serviceImpl:
@DubboService
@Service
public class StudentServiceImpl implements StudentService {
    
    
    @Override
    public String show(){
    
    
        return "hello world2";
    }
}

4.启动类上加@EnableDubbo,@EnableDubboConfig注解

@SpringBootApplication
@EnableDubbo
@EnableDubboConfig
public class StudentApplicationStarter {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(StudentApplicationStarter.class,args);
    }
}

3.创建工程consumer

1.导入依赖

	<dependencies>
        <!-- dubbo启动器 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>3.0.4</version>
        </dependency>
        <!-- apache 提供的zookeeper客户端访问框架 -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>5.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>5.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-x-discovery</artifactId>
            <version>5.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>dubboserver</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

2.yml配置

server:
  port: 8002
spring:
  application:
    name: teacher
# dubbo相关配置。
dubbo:
  application: # 注意:部分低版本dubbo中。dubbo.application.id必要。
    id: teacher # 可选配置,dubbo服务的唯一命名。默认${dubbo.application.name}
    name: teacher # 必要配置,dubbo服务的唯一命名。
  registry: # 配置注册中心地址。必要配置。
    address: zookeeper://127.0.0.1:32768  # 注册中心地址
    timeout: 300000  # 超时配置
  protocol: # dubbo的provider启动后,监听什么端口,处理什么协议。
    name: dubbo # dubbo协议。默认值。推荐使用。
    port: 20880 # provider监听的端口。默认值20880。

3.远程调用provider中的业务层代码
注意: 创建远程接口的包名+类名要一致

@DubboReference:
1、根据配置连接到注册中心找同名的提供者同名:[包名+类名一致]订阅
2、dubbo根据订阅的信息创建该接口的动态代理对象﹑并把动态代理对象放到spring容器中
3、然后把代理对象注入到改接口中和@Autowired 注解功能是一样的

service:
public interface StudentService {
    
    
    String show();
}

serviceImpl:
@Service
public class TeacherServiceImpl implements TeacherService {
    
    
1、根据配置连接到注册中心找同名的提供者同名:[包名+类名一致]订阅
2、dubbo根据订阅的信息创建该接口的动态代理对象﹑并把动态代理对象放到spring容器中
3、然后把代理对象注入到改接口中和@Autowired 注解功能是一样的
    @DubboReference
    private StudentService studentService;

    public String show(){
    
    
        return studentService.show();
    }
}

@RestController
public class TeacherController 
    @Autowired
    private TeacherService teacherService;
    @RequestMapping("/fs")
    public String show(){
    
    
        return teacherService.show();
    }
}

4.启动类上加注解

@SpringBootApplication
@EnableDubbo
@EnableDubboConfig
public class TeacherApplicationStarter {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(TeacherApplicationStarter.class,args);
    }
}

5.访问http://localhost:8002/fs,浏览器打印hello world

4.提取业务层接口:新建模块service_mg

将上述provider的接口和consumer的接口提取 到这个模块,并让着两个模块依赖service_mg即可
注意: 这两个接口的包所在的层次路径要一致

负载均衡策略

在consumer 和 provider 中都可以指定,在其中一个指定即可

指定负载均衡策略 (dubbo内置有4种策略) 默认是 随机
1.Random: 随机。随机访问集群中节点。访问概率和权重有关。 默认
2.RoundRobin: 轮询,访问频率和权重有关,权重:占有比例,集群中每个项目部署的服务器的性能可能不同,性能好的服务器权重应该高一些如果权重相同 策略变成了轮询
3.LeastActive: 活跃数相同的随机,不同的活跃数高的放前面。判断哪一个provider处理的请求少就交给谁处理
4.ConsistentHash: 一致性Hash。相同参数请求总是发到一个提供者。
provider

在provider中指定(推荐)
1.局部:直接在注解中增加属性即可@DubboService(loadbalance ="roundrobin" ,weight = 1)注意weight默认执是-1,即使是轮询也要指定权重,不要用默认值
2.全局:在配置文件中指定
dubbo:
  provider: # 给当前应用中所有的服务提供者配置共性
  loadbalance: roundrobin # 所有provider的默认负载均衡策略是什么。默认为random
  weight: 3 # 所有provider节点的权重是多少。默认-1       
局部优先級>全局优先級      

consumer

在consumer中指定
1.局部: @DubboReference(loadbalance = "roundrobin" ) 增加 属性即可 但是注意在消费者指定没有权重的概念
2.全局:在配置文件中指定
dubbo:
  consumer: # 给当前应用中所有的服务消费者配置共性
  loadbalance: random # 所有的服务消费者默认负载均衡策略是什么。
局部优先級>全局优先級

配置Consumer检查操作

绝大多数的dubbo版本,默认情况下Consumer在启动的时候就会创建 Provider代理对象 进行注入
如果没有启动Provider 就没有办法进行代理对象创建 完成注入,Consumer代码在启动的时候就会报错
@DubboReference(check = false)代表的是启动的时候不会创建代理对象,在访问的时候才会创建这个代理对象

1.注解解决
@DubboReference(check = false)
2.全局配置解决:
dubbo:
  consumer: # 给当前应用中所有的服务消费者配置共性
  check: false # 所有的服务消费者,启动时不创建provider代理对象。使用时重新发现并创建代理。

配置dubbo协议的payload

Dubbo框架在使用dubbo协议实现远程服务调用的时候,默认限制请求和应答数据最大为8M。如果超出范围则抛出异常。可以通过配置设置payload容量。

dubbo:
  protocol: 
    payload: 838860800 # 配置请求响应传输的数据最大容量,不建议修改。默认8M

group和version

1.如果一个实现类对应多个接口 注册到注册中心上接口可以使用@DubboService(interfaceClass = 或interfaceName = )

2.如果一个接口对应多个实现类 这个时候必须增加 group = “xy”,version = “2.0” 进行区分 如果在提供者增加了分组和版本号 在消费者处也需要增加对应的
分组和版本号 进行区分调用
Dubbo框架支持服务分组注册和服务多版本发布。即相同的接口发布的服务,也可以用组来维护。且可以同时提供若干不同版本的服务提供者实现。

1.provider注解配置:
@DubboService(group = "test", version = "1.0")

2.consumer解配置:
注意:当Provider注册服务时,约束了分组或版本,Consumer则必须提供相应配置,否则无法发现服务
@DubboReference(group = "test", version = "1.0")

执行过程

1、调用过程从一个Proxy开始,Proxy持有了一个Invoker对象。
2、然后触发invoke调用。在invoke调用过程中。
3、在调用之前会通过Directory获取所有可以调用的远程服务Invoker列表。接下来就会调用LoadBalance方法做负载均衡,最终选出一个可以调用的Invoker。
4、这个Invoker在调用之前又会进入一个过滤器链,这个过滤器链通常是处理上下文、限流、计数等。
5、接着,会使用Client做数据传输。此时就会用到Codec接口做私有协议的构造。
6、构造完成之后,就对数据包做序列化(Serialization),然后传输到服务提供者端。
7、服务提供者接收到数据包,也会使用Codec处理协议头及一些半包、粘包等。处理完成之后再对完整的数据报文做反序列化处理。
8、随后,这个Request会被分配到线程池(ThreadPool)中进行处理。Server会处理这些Request,根据请求查找对应的Exporter(它内部持有了Invoker。Invoker是被用装饰器模式一层一层套了很多Filter的,因此在调用最终的实现类之前,又会经过一个服务提供者端的过滤器链。)
9、最终,原路返回结果。

猜你喜欢

转载自blog.csdn.net/m0_56182317/article/details/130319599