dubbo

一、集群和分布式

集群:就是很多人一起,干一样的事情

分布式:很多人一起干不一样的事情,但这些不一样的事情合起来就是一件大事,即若干独立系统的集合,但是用户使用起来还是在使用一套系统

特点:高性能,高可用,可伸缩,高可扩展

二、应用架构的发展演变

1.单一架构

把所有的应用放到一台服务器上

优点:开发简单部署简单

缺点:不容易扩展,不容易维护,性能提升难,项目启动慢,可靠性差,可伸缩性差

2.垂直架构 

将大应用拆分成小应用(一般按照业务进行分),根据不同的访问频率来确定部署的服务器数量

缺点:界面+业务逻辑的实现分离,应用之间不可能完全独立,大量的应用之间需要交付

3.分布式架构(基于RPC:远程过程调用)

在垂直架构的基础上,将公共业务模块抽取出来,作为独立的服务,供其他调用者消费,以实现服务的共享和重用。

4.SOA架构

将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来

 5.微服务架构

强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。 微服务架构 = 80%的SOA服务架构思想 + 100%的组件化架构思想 + 80%的领域建模思想

三、RPC

核心模块:通讯,序列化

四、dubbo概述(一个高性能、轻量级的 Java RPC 框架)

Provider:暴露服务的服务提供方

Container:服务运行容器

Consumer:调用远程服务的服务消费方

Registry:服务注册与发现的注册中心

Monitor:统计服务的调用次数和调用时间的监控中心

 五、注册中心

zookeeper:更改配置文件要

进去conf目录复制zoo_sample.cfg然后更改复制后的文件  地址为你安装的zookeeper的地址

dataDir=D:\apache-zookeeper-3.6.3-bin\data

dataLogDir=D:\apache-zookeeper-3.6.3-bin\log

如果更在在服务器上的启动端口添加配置:admin.serverPort=没有占用的端口号

六、监控中心

去gitHub下载dubbo-admin  

进入到dubbo-admin-develop目录下输入mvn clean package

启动后端 

切换到目录dubbo-Admin-develop\dubbo-admin-distribution\target>然后输入

java -jar ./dubbo-admin-0.3.0.jar

 启动前端 

dubbo-admin-ui 目录下执行命令 npm run dev

访问

浏览器输入http://localhost:8082 用户名密码都是root

七、dubbo的使用

创建三个模块:消费者  提供者  公共接口模块

1.api-interface模块:公共接口层(作用:定义公共接口,也可以导入公共依赖)

实体类模型

package com.gl.pojo;

import java.io.Serializable;

/**
 * @description:
 * @author: GL
 * @create: 2021-10-26 10:36
 **/
public class UserAddress implements Serializable {
    private Integer id;
    private String userAddress;
    private String userId;
    private String consignee;
    private String phoneNum;
    private String isDefault;

    public UserAddress() {
    }

    public UserAddress(Integer id, String userAddress, String userId, String consignee, String phoneNum, String isDefault) {
        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;
    }

    @Override
    public String toString() {
        return "UserAddress{" +
                "id=" + id +
                ", userAddress='" + userAddress + '\'' +
                ", userId='" + userId + '\'' +
                ", consignee='" + consignee + '\'' +
                ", phoneNum='" + phoneNum + '\'' +
                ", isDefault='" + isDefault + '\'' +
                '}';
    }
}

接口提取

UserService

package com.gl.service;

import com.gl.pojo.UserAddress;

import java.util.List;

/**
 * @description:根据id查询所有的信息
 * @author: GL
 * @create: 2021-10-26 10:39
 **/
public interface UserService {
    public List<UserAddress> getUserAddressList(String userId);
}

OrderService

package com.gl.service;

import java.util.List;


import com.gl.pojo.UserAddress;

public interface OrderService {
	
	/**
	 * 初始化订单
	 * @param userId
	 */
	public List<UserAddress> initOrder(String userId);

}

提供者模块(provider-service)

 pom依赖

    <dependencies>
      <!--定义的公共接口的哪个类-->
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>api-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--        dubbo依赖-->
        <!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.9</version>
        </dependency>
        <!--        zookeeper依赖-->
        <!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--        【新版的坑】zookeeper及其依赖包,解决日志冲突,还需要剔除日志依赖;-->
        <!-- 引入zookeeper -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.12.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.14</version>
            <!--排除这个slf4j-log4j12-->
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

业务层(UserServiceImpl)

package com.gl.service.impl;

import com.gl.pojo.UserAddress;
import com.gl.service.UserService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * @description:
 * @author: GL
 * @create: 2021-10-26 15:32
 **/
@DubboService
@Component
public class UserServiceImpl implements UserService {
    @Override
    public List<UserAddress> getUserAddressList(String userId) {
        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);
    }
}

resources


dubbo:
  application:
#    指定当前服务的名字
    name: user-provider
#    指定注册中心的地址
  registry:
    address: zookeeper://127.0.0.1:2181
#    指定通信规则(通信协议 通信端口)
  protocol:
    name: dubbo
    port: 20880
#    连接监控中心
  monitor:
    protocol: registry
#    注解方式要扫描的包
  scan:
    base-packages: com.gl
server:
  port: 9001

消费者模块(consumer-service) 

pom和提供者一样

业务层(OrderServiceImpl)

package com.gl.service.impl;

import com.gl.pojo.UserAddress;
import com.gl.service.OrderService;
import com.gl.service.UserService;
import org.apache.dubbo.config.annotation.DubboReference;

import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @description:
 * @author: GL
 * @create: 2021-10-26 15:32
 **/
@Service
@DubboService
public class OrderServiceImpl implements OrderService {
    @DubboReference
    UserService userService;
    @Override
    public List<UserAddress> initOrder(String userId) {
        System.out.println("用户id:"+userId);
        List<UserAddress> userAddressList = userService.getUserAddressList(userId);
        return userAddressList;
    }
}

controller

package com.gl;

import com.gl.pojo.UserAddress;
import com.gl.service.OrderService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @description:
 * @author: GL
 * @create: 2021-10-26 15:57
 **/
@RestController
public class controller {
    @Autowired
    private OrderService orderService;

    @GetMapping("/initOrder/{userId}")
    public List<UserAddress> initOrder(@PathVariable String userId) {
        return orderService.initOrder(userId);
    }
}

resources

server:
  port: 9002
dubbo:
  application:
    name: order-consumer
  registry:
    address: zookeeper://127.0.0.1:2181
  monitor:
    protocol: registry

八、dubbo的一些配置

1.启动时检查

意思就是提供者需要注册到服务中心,然后消费者去拿但是没有提供者,只有消费者然后就会报如下的错误

Failed to check the status of the service com.gl.service.UserService. No provider available for the service com.gl.service.UserService from the url consumer://192.168.76.1/com.gl.service.UserService?application=order-consumer&category=providers,configurators,routers&dubbo=2.0.2&id=org.apache.dubbo.config.RegistryConfig#0&init=false&interface=com.gl.service.UserService&metadata-type=remote&methods=getUserAddressList&pid=13140&qos.enable=false&release=2.7.9&side=consumer&sticky=false&timestamp=1635239482089 to the consumer 192.168.76.1 use dubbo version 2.7.9

解决方式:(在调用才会去检查)

#    配置统一的规则,所有的服务都不检查
dubbo: 
 consumer:
    check: false

单个不检查

@DubboReference(check = false)

2.超时

由于网络或服务端不可靠,会导致调用出现一种不确定的中间状态(超时)。为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间。

提供者

全局配置

dubbo.provider timeout=""

单个配置

@DubboReference(timeout= “”)

消费者

全局配置

dubbo.consumer timeout=""

单个配置

@DubboReference(timeout= “”)

配置原则

方法级配置别优于接口级别  Consumer端配置 优于 Provider配置  最后才是全局配置

3.重试(不含第一次)

失败自动切换,当出现失败,重试其它服务器,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数。

幂等设置重试次数【查询,删除,修改】:最后的值是否一致

非幂等不设置重试次数【增加】

4.版本号

在提供端的配置

在消费端

最终效果

 九、dubbo高可用

 1.zookeeper宕机与dubbo直连(zookeeper注册中心宕机,消费者还是能够调到提供方)

  1. 监控中心宕掉不影响使用,只是丢失部分采样数据
  2. 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
  3. 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
  4. 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
  5. 服务提供者无状态,任意一台宕掉后,不影响使用
  6. 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

直连的方式:

 2.集群下dubbo的负载均衡(默认为random)

通过 loadbalance = ""来设置策略

Random LoadBalance

随机,按权重设置随机概率。

在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。

RoundRobin LoadBalance

轮循,按公约后的权重设置轮循比率。

存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

LeastActive LoadBalance

最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。

使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

ConsistentHash LoadBalance

一致性 Hash,相同参数的请求总是发到同一提供者。

当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

3. 整合hystrix,服务降级,服务容错

服务降级:

当服务器压力剧增,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。

1.mock=force:return+null 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。对应控制台的屏蔽

2.还可以改为 mock=fail:return+null 表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。对应控制台的容错

集群容错:使用cluster=" "来配置

Failover Cluster

失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)

Failfast Cluster

快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录

Failsafe Cluster

失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

Failback Cluster

失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。

Forking Cluster

并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。

Broadcast Cluster

广播调用所有提供者,逐个调用,任意一台报错则报错 [2]。通常用于通知所有提供者更新缓存或日志等本地资源信息。

整合hystrix:

Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能

在pom加入spring-cloud-starter-netflix-hystrix依赖

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>1.4.4.RELEASE</version>
 </dependency>

 然后在Application类上增加@EnableHystrix来启用hystrix starter:

@EnableHystrix

配置提供方

在Dubbo的Provider上增加@HystrixCommand配置,这样子调用就会经过Hystrix代理。

配置服务方

测试结果 

正常

错误:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值