Dubbo Nacos Sentinel 整合使用

Dubbo Nacos Sentinel 整合使用

上一篇

nacos-dubbo-sentinel-provider: 工程 将dubbo 调用接口映射到Sentinel 控制管理后台管理,并且根据nacos 配置进行刷新流控规则

gradle配置

plugins {
    id 'org.springframework.boot' version '2.2.11.RELEASE'
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'

}

ext {
    set('springCloudAlibabaVersion', "2.2.1.RELEASE")
}

dependencies {
    implementation 'com.alibaba.cloud:spring-cloud-starter-dubbo'
    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config'
    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery'
    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel'
    implementation 'com.alibaba.csp:sentinel-datasource-nacos'
    implementation 'com.alibaba.csp:sentinel-apache-dubbo-adapter'
    implementation project(':alibb-dubbo-mineserviceapi')//依赖同一个父模块的子模块
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

dependencyManagement {
    imports {
        mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:${springCloudAlibabaVersion}"
    }
}

boostrap.properties

#bootstrap.properties -> bootstrap.yml -> application.properties -> application.yml ,加载顺序
#因为需要启动的时候初始化(配置中心)配置(因为需要先初始化配置),所以关于配置nacos的配置放在这,这样才能去nacos配置中心拿到相关的数据

#配置中心的地址
spring.cloud.nacos.config.server-addr=ip:port

# DataID属性的值为配置文件名格式为:${prefix}-${spring.profile.active}.${file-extension}
#nacos 配置中心配置的 dataId的命名得加上后缀
#在${prefix} 通过 spring.cloud.nacos.config.prefix 定义,没有定义的时候默认是spring.application.name
#spring.profile.active 当前的环境的配置,没有定义,则对应的连接符- 也不会存在->${prefix}.${file-extension}
#file-extension 配置文件的后缀,也代表了这个配置的配置内容的格式
spring.cloud.nacos.config.file-extension=yaml
#spring.cloud.nacos.config.prefix=nacos-dubbo-sentinel-provider

# nacos 数据模型
#namespace命名空间->Group->services/dataId ,主要的目的都是为了数据隔离(配置的隔离)
#namespace:命名空间,对不同的环境(一定要求)进行隔离
#group:分组,将若干服务或配置集(配置文件)归为一组,通常这些服务或者配置有一定的共同点(按区分的要求)
#service:服务,一个提供服务的应用实例(比如java实例),不同namespace的不能相互调用
#dataId:配置或者一组配置的集合(配置文件)
spring.cloud.nacos.config.namespace=public
spring.cloud.nacos.config.group=DEFULT_GROUP

application.properties

server.port=8082

dubbo.application.id=nacos-dubbo-sentinel-provider
dubbo.application.name=nacos-dubbo-sentinel-provider
spring.application.name=nacos-dubbo-sentinel-provider

#sentinel 控制台地址
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8888
#本地与控制台连接的占用本地的端口
spring.cloud.sentinel.transport.port=9501

#注册地址 nacos 做注册中心
dubbo.protocol.name=dubbo
dubbo.protocol.port=9101
dubbo.registry.address=spring-cloud://ip
spring.cloud.nacos.discovery.server-addr=ip:port
dubbo.cloud.subscribed-services=
#sentinel 数据源配置
#配置流控规则
spring.cloud.sentinel.datasource.flow.nacos.server-addr=ip:port
spring.cloud.sentinel.datasource.flow.nacos.data-id=${spring.application.name}-flow-rules
spring.cloud.sentinel.datasource.flow.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.flow.nacos.rule-type=flow
package com.study.nacosdubbosentinelprovider;

import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@DubboComponentScan//记得加不然会报一个说 ip 拼写错误的错
@EnableDiscoveryClient
public class NacosDubboSentinelProviderApplication {

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

}

package com.study.nacosdubbosentinelprovider.sentineldubbo;

import com.study.alibbdubbomineserviceapi.demo.NacosDemoService;
import org.apache.dubbo.config.annotation.Service;

/**
 * @Auther: jmx
 * @Date: 2020/12/24 01:50
 * @Description: NacosDubboProvider
 * @Version 1.0.0
 */
@Service(cluster = "failfast",loadbalance="roundrobin",weight = 2)
public class SentinelDubboProvider implements NacosDemoService {
    @Override
    public String sayHello() {
        return "SentinelDubboProvider say hello";
    }
}

工程:nacos-dubbo-sentinel-consumer 消费者工程 将dubbo 调用接口映射到Sentinel 控制管理后台管理,并且根据nacos 配置进行刷新流控规则
gradle 配置

plugins {
    id 'org.springframework.boot' version '2.2.11.RELEASE'
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'

}

ext {
    set('springCloudAlibabaVersion', "2.2.1.RELEASE")
}

dependencies {
    implementation 'com.alibaba.cloud:spring-cloud-starter-dubbo'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config'
    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery'
    implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel'
    implementation 'com.alibaba.csp:sentinel-datasource-nacos'
    implementation project(':alibb-dubbo-mineserviceapi')//依赖同一个父模块的子模块
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}


dependencyManagement {
    imports {
        mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:${springCloudAlibabaVersion}"
    }
}

bootstrap.properties

#bootstrap.properties -> bootstrap.yml -> application.properties -> application.yml ,加载顺序
#因为需要启动的时候初始化(配置中心)配置(因为需要先初始化配置),所以关于配置nacos的配置放在这,这样才能去nacos配置中心拿到相关的数据

#配置中心的地址
spring.cloud.nacos.config.server-addr=ip:port

# DataID属性的值为配置文件名格式为:${prefix}-${spring.profile.active}.${file-extension}
#nacos 配置中心配置的 dataId的命名得加上后缀
#在${prefix} 通过 spring.cloud.nacos.config.prefix 定义,没有定义的时候默认是spring.application.name
#spring.profile.active 当前的环境的配置,没有定义,则对应的连接符- 也不会存在->${prefix}.${file-extension}
#file-extension 配置文件的后缀,也代表了这个配置的配置内容的格式
spring.cloud.nacos.config.file-extension=yaml
#spring.cloud.nacos.config.prefix=nacos-dubbo-sentinel-consumer

# nacos 数据模型
#namespace命名空间->Group->services/dataId ,主要的目的都是为了数据隔离(配置的隔离)
#namespace:命名空间,对不同的环境(一定要求)进行隔离
#group:分组,将若干服务或配置集(配置文件)归为一组,通常这些服务或者配置有一定的共同点(按区分的要求)
#service:服务,一个提供服务的应用实例(比如java实例),不同namespace的不能相互调用
#dataId:配置或者一组配置的集合(配置文件)
spring.cloud.nacos.config.namespace=public
spring.cloud.nacos.config.group=DEFULT_GROUP

application.properties

server.port=8081
spring.application.name=nacos-dubbo-sentinel-consumer
#sentinel
#指定应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer
spring.cloud.sentinel.transport.port=9500

#spring.cloud.sentinel.transport.client-ip=如果有确认IP最好配置一下,不然是会有问题的
#限流规则的控制台
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8888
#dubbo
dubbo.application.name=nacos-dubbo-sentinel-consumer
dubbo.application.id=nacos-dubbo-sentinel-consumer
dubbo.protocol.name=dubbo
#注册地址 nacos 做注册中心
dubbo.registry.address=spring-cloud://ip
spring.cloud.nacos.discovery.server-addr=ip:port
#关注的服务
dubbo.cloud.subscribed-services=nacos-dubbo-sentinel-provider
#spring.cloud.sentinel.filter.enabled=true
spring.mvc.servlet.load-on-startup=10

#sentinel 数据源配置
#配置流控规则
spring.cloud.sentinel.datasource.flow.nacos.server-addr=ip:port
spring.cloud.sentinel.datasource.flow.nacos.data-id=${spring.application.name}-flow-rules
spring.cloud.sentinel.datasource.flow.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.flow.nacos.rule-type=flow

#配置降级规则
#spring.cloud.sentinel.datasource.degrade.nacos.server-addr=ip:port
#spring.cloud.sentinel.datasource.degrade.nacos.data-id=${nacos-dubbo-sentinel-consumer}-degrade-rules
#spring.cloud.sentinel.datasource.degrade.nacos.group-id=SENTINEL_GROUP
#spring.cloud.sentinel.datasource.degrade.nacos.rule-type=degrade

#触发限流跳转页面
#spring.cloud.sentinel.block-page=

#定义资源过滤的条件
#spring.cloud.sentinel.filter.url-patterns=/**


package com.study.nacosdubbosentinelconsumer;

import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@DubboComponentScan
@EnableDiscoveryClient
public class NacosDubboSentinelConsumerApplication {

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

}

package com.study.nacosdubbosentinelconsumer.sentineldubbo;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.AbstractSentinelInterceptor;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebInterceptor;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.UrlCleaner;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.study.alibbdubbomineserviceapi.demo.NacosDemoService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Auther: jmx
 * @Date: 2020/12/20 18:30
 * @Description: SentinelDubboApi
 * @Version 1.0.0
 */
//http 请求的都会被SentinelWebInterceptor 拦截然后定义资源名,所以直接到控制台后面设置规则就好了,AbstractSentinelInterceptor 这里定义资源名
@RequestMapping("/sentineldubbo")
@RefreshScope
@RestController
public class SentinelDubboApi {

    @Reference(mock = "com.study.nacosdubbosentinelconsumer.sentineldubbo.mock.SentinelDubboMockProvider")
    private NacosDemoService demoService;

    @RequestMapping("/sayhello")
    public String sayHello(String id,HttpServletRequest request)  {

        return demoService.sayHello();
    }
    @GetMapping("/get/{id}")
    public String getInfo(@PathVariable("id") int id){
        return id+1+ "" ;
    }

}

package com.study.nacosdubbosentinelconsumer.sentineldubbo.mock;

import com.study.alibbdubbomineserviceapi.demo.NacosDemoService;

/**
 * @Auther: jmx
 * @Date: 2020/12/20 18:37
 * @Description: SentinelDubboMockProvider NacosDemoService服务方挂掉之后用得降级服务
 * @Version 1.0.0
 */
public class SentinelDubboMockProvider implements NacosDemoService {

    public SentinelDubboMockProvider() {
        System.out.println("SentinelDubboMockProvider created .......");
    }

    @Override
    public String sayHello() {
        return "SentinelDubboMockProvider say hello";
    }
}

package com.study.nacosdubbosentinelconsumer.sentineldubbo.handler;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.UrlCleaner;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

@Service
public class DefineUrlClean implements UrlCleaner{

    //在SentinelWebInterceptor 用于映射解析访问的请求地址,将其定义为正确的资源名称,在1.7版本,主要用于解决 映射/get/{id} 中 /get/1 和 /get/2 属于不同资源
    //而Sentinel 默认资源数是6000,超出的将不会生效
    //在1.8 中则不会 映射/get/{id} 中 /get/1 和 /get/2  定义的资源名就是 /get/{id}
    @Override
    public String clean(String originUrl) {
        if(StringUtils.isEmpty(originUrl)){
            return originUrl;
        }
        if (originUrl.startsWith("/sentineldubbo/get/{id}")){
            return "/sentineldubbo/get/{param}";
        }
        return originUrl;
    }
}

package com.study.nacosdubbosentinelconsumer.sentineldubbo.handler;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Service
public class DefineBlockHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {

        System.out.println(request.getRequestURI());
        e.printStackTrace();
        response.setHeader("Content-Type","application/json;charset=UTF-8");
        String message = "{\n" +
                "\t\"code\":10000,\n" +
                "\t\"msg\":\"访问人数过多\n" +
                "}";
        response.getWriter().write(message);

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值