当前位置:   article > 正文

SpringCloud Alibaba配置使用整合_@reference url

@reference url

一、Nacos注册中心

1、pom.xml配置依赖

  1. <!-- nacos作为注册发现中心 -->
  2. <dependency>
  3. <groupId>com.alibaba.cloud</groupId>
  4. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  5. </dependency>

2、application.yml配置Nacos服务中心地址

  1. spring:
  2. application:
  3. name: product
  4. cloud:
  5. nacos:
  6. discovery:
  7. server-addr: 127.0.0.1:8848

3、通过@NacosInjected注入Nacos地NamingService

4、使用Nacos提供的OpenAPI方法

(1)注册实例

  1. registerInstance(serviceName, ip, port)
  2. registerInstance(serviceName, ip, port, clusterName)
  3. registerInstance(serviceName, instance)

(2)获取实例

  1. getAllInstances(serviceName)
  2. getAllInstances(serviceName, clusters)

(3)监听服务

  1. subscribe(serviceName, listener)
  2. subscribe(serviceName, clusters, listener)

【Dubbo】 

5、Dubbo使用Nacos实现注册中心

(1)application.properties

  1. dubbo.application.name: spring-boot-dubbo-nacos-sample
  2. dubbo.registry.address=nacos://127.0.0.1:8848
  3. dubbo.protocol.name=dubbo
  4. dubbo.protocol.port=20880

(2)通过Dubbo的@Service声明

(3)启动类使用@DubboComponentScan扫描@Service

二、Nacos配置中心

1、pom.xml配置依赖

  1. <!-- nacos作为配置中心 -->
  2. <dependency>
  3. <groupId>com.alibaba.cloud</groupId>
  4. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  5. </dependency>

2、bootstrap.properties配置Nacos配置中心地址

  1. spring.cloud.nacos.config.server-addr=127.0.0.1:8848
  2. spring.cloud.nacos.config.namespace=6ca49aac-50ec-4e6f-8686-70bb11922fdd

3、使用注解从NacosServer动态读取配置

  1. @NacosPropertySource(dataId = "example", autoRefreshed = true)
  2. @RestController
  3. public class NacosConfigController{
  4. @NacosValue(value = "${info:Local Hello World}", autoRefreshed = true)
  5. private String info;
  6. @GetMapping("/config")
  7. public String get(){
  8. return info;
  9. }
  10. }

(1)@NacosPropertySource:用于加载dataId为example地配置源,autoRefreshed表示开启自动更新;

(2)@NacosValue:设置属性的默认值

4、使用Nacos提供的OpenAPI方法

三、Dubbo

【服务提供者】

1、pom.xml配置依赖

  1. <dependency>
  2. <groupId>com.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.apache.dubbo</groupId>
  7. <artifactId>dubbo-spring-boot-starter</artifactId>
  8. <version>2.7.5</version>
  9. </dependency>

2、application.properties配置Dubbo服务

  1. spring.application.name=spring-dubbo-demo
  2. dubbo.application.name=springboot-provider
  3. dubbo.protocol.name=dubbo
  4. dubbo.protocol.port=20880
  5. dubbo.registry.address=N/A

3、声明Dubbo提供的@Service注解发布服务

  1. @Service
  2. public class HelloServiceImpl implements HelloService{
  3. @value("${dubbo.application.name}")
  4. private String servicename;
  5. @Override
  6. public String sayHello(String name){
  7. return servicename;
  8. }
  9. }

4、启动方法上添加@DubboComponentScan,用来扫描Dubbo声明的@Service

  1. @DubboComponentScan
  2. @SpringBootApplication
  3. public class ProviderApplication{
  4. public static void main(Sting[] args){
  5. SpringApplication.run(ProviderApplication.class, args);
  6. }
  7. }

【服务调用者】

1、pom.xml配置依赖

  1. <dependency>
  2. <groupId>org.apache.dubbo</groupId>
  3. <artifactId>dubbo-spring-boot-starter</artifactId>
  4. <version>2.7.5</version>
  5. </dependency>

2、application.properties配置Dubbo服务

dubbo.application.name=springboot-consumer

3、使用Dubbo提供的@Reference注解获取远程代理服务对象

  1. @Reference(url = "dubbo://192.168.13.1:20880/com.gupaoedu.book.dubbo.helloService")
  2. private HelloService helloService;

【高级配置】 

1、集群容错

@Service(cluster = "failfast")

容错模式

(1)Failover Cluster:失败自动切换。调用失败后,切换到集群中其他机器,默认重试两次。

(2)Failfast Cluster:快速失败。调用失败后,立即报错,只发起依次调用。

(3)Failsafe Cluster:失败安全。出现异常时,直接忽略。

(4)Failback Cluster:失败后自动回复。后台记录失败请求,定时重发。

(5)Forking Cluster:并行调用集群中的多个服务,只要其中一个成功就返回。

(6)Broadcast Cluster:广播调用所有的服务提供者,任意一个服务报错则表示服务调用失败。

2、负载均衡

@Service(cluster = "failfast", loadbalance = "roundrobin")

负载均衡策略

(1)Random LoadBalance:随机算法。可能针对性能较好的服务器设置较大的权重值。

(2)RoundRobin LoadBalance:轮询。按照公约后的权重设置轮询比例。

(3)LeastActive LoadBalance:最少活跃调用书。处理较慢的节点将会收到更少的请求。

(4)ConsistentHash LoadBalance:一致性Hash。相同参数的请求总是发送到同一个服务提供者。

3、服务降级

(1)创建降级本地数据默认返回

  1. public class MockHelloService implements HelloService{
  2. @Override
  3. public String sayHello(String s){
  4. return "Sorry, 服务无法访问, 返回降级数据";
  5. }
  6. }

(2)@Reference注解增加Mock参数

  1. @Reference(mock = "com.gupaoedu.book.springcloud.springclouddubboconsumer.MockHelloService", cluster = "failfast")
  2. private HelloService helloService;

4、主机绑定

(1)Dubbo服务对外发布的IP地址,默认顺序

  1. 查找环境变量中的DUBBO_IP_TO_BIND属性配置的IP地址
  2. 查找dubbo.protocol.host属性配置的IP地址,默认是空
  3. 通过LocalHost.getHostAddress获取本机IP地址
  4. 注册中心的地址,使用Socket通信连接到注册中心的地址后,使用for循环通过socket.getLocalAddress().getHostAddress()扫描各个网卡获取网卡IP地址

(2)服务消费者无法正常调用情况解决办法

  1. /etc/hosts中配置机器名对应正确的IP地址映射
  2. 环境变量添加DUBBO_IP_TO_BIND或者DUBBO_IP_TO_REGISTRY属性
  3. 通过dubbo.protocol.host设置主机地址

无法正常调用原因:Dubbo通过获取本机的hostname映射IP地址,如果IP地址错误,依然会注册ZooKeeper,并且正常启动。 

四、Feign

1、pom.xml引入依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-openfeign</artifactId>
  4. </dependency>

2、定义接口,通过@FeignClient注解指定服务名来绑定服务

        声明接口的每一个方法都是调用哪个远程服务的哪个请求

  1. @FeignClient("whalemall-coupon")
  2. public interface CouponFeignService {
  3. @PostMapping("/coupon/spubounds/save")
  4. R saveSpuBounds(@RequestBody SpuBoundTo spuBoundTo);
  5. @PostMapping("/coupon/skufullreduction/saveinfo")
  6. R saveSkuReduction(@RequestBody SkuReductionTo skuReductionTo);
  7. }

3、启动类通过@EnableFeignClients注解开启Spring Cloud Feign

  1. @EnableFeignClients(basePackages = "com.island.whalemall.product.feign")
  2. @EnableDiscoveryClient
  3. @MapperScan("com.island.whalemall.product.dao")
  4. @SpringBootApplication
  5. public class WhalemallProductApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(WhalemallProductApplication.class, args);
  8. }
  9. }

五、Gateway

1、pom.xml添加依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-gateway</artifactId>
  4. </dependency>

2、application.yml文件中添加Gateway的路由配置

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. # 商品服务
  6. - id: product_route
  7. uri: lb://whalemall-product
  8. predicates:
  9. - Path=/api/product/**
  10. filters:
  11. - RewritePath=/api/(?<segment>.*),/$\{segment}

六、Seate

七、OSS

1、pom.xml添加依赖

  1. <dependency>
  2. <groupId>com.aliyun.oss</groupId>
  3. <artifactId>aliyun-sdk-oss</artifactId>
  4. <version>3.10.2</version>
  5. </dependency>

2、使用OSS域名新建OSSClient

  1. // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
  2. String endpoint = "yourEndpoint";
  3. // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
  4. String accessKeyId = "yourAccessKeyId";
  5. String accessKeySecret = "yourAccessKeySecret";
  6. // 创建OSSClient实例。
  7. OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
  8. // 关闭OSSClient。
  9. ossClient.shutdown();

3、创建examplebucket存储空间

  1. // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
  2. String endpoint = "yourEndpoint";
  3. // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
  4. String accessKeyId = "yourAccessKeyId";
  5. String accessKeySecret = "yourAccessKeySecret";
  6. // 填写Bucket名称,例如examplebucket。
  7. String bucketName = "examplebucket";
  8. OSS ossClient = null;
  9. try {
  10. // 创建OSSClient实例。
  11. ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
  12. // 创建存储空间。
  13. ossClient.createBucket(bucketName);
  14. } catch (OSSException e){
  15. e.printStackTrace();
  16. } finally {
  17. // 关闭OSSClient。
  18. ossClient.shutdown();
  19. }

4、通过流式上传方式上传文件到OSS

  1. // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
  2. String endpoint = "yourEndpoint";
  3. // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
  4. String accessKeyId = "yourAccessKeyId";
  5. String accessKeySecret = "yourAccessKeySecret";
  6. // 填写Bucket名称,例如examplebucket。
  7. String bucketName = "examplebucket";
  8. // 填写文件名。文件名包含路径,不包含Bucket名称。例如exampledir/exampleobject.txt。
  9. String objectName = "exampledir/exampleobject.txt";
  10. OSS ossClient = null;
  11. try {
  12. // 创建OSSClient实例。
  13. ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
  14. String content = "Hello OSS";
  15. ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
  16. } catch (OSSException e){
  17. e.printStackTrace();
  18. } finally {
  19. // 关闭OSSClient。
  20. ossClient.shutdown();
  21. }

5、通过流式下载方式从OSS下载文件

  1. // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
  2. String endpoint = "yourEndpoint";
  3. // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
  4. String accessKeyId = "yourAccessKeyId";
  5. String accessKeySecret = "yourAccessKeySecret";
  6. // 填写Bucket名称,例如examplebucket。
  7. String bucketName = "examplebucket";
  8. // 填写文件名。文件名包含路径,不包含Bucket名称。例如exampledir/exampleobject.txt。
  9. String objectName = "exampledir/exampleobject.txt";
  10. OSS ossClient = null;
  11. try {
  12. // 创建OSSClient实例。
  13. ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
  14. // 调用ossClient.getObject返回一个OSSObject实例,该实例包含文件内容及文件元信息。
  15. OSSObject ossObject = ossClient.getObject(bucketName, objectName);
  16. // 调用ossObject.getObjectContent获取文件输入流,可读取此输入流获取其内容。
  17. InputStream content = ossObject.getObjectContent();
  18. if (content != null) {
  19. BufferedReader reader = new BufferedReader(new InputStreamReader(content));
  20. while (true) {
  21. String line = reader.readLine();
  22. if (line == null) break;
  23. System.out.println("\n" + line);
  24. }
  25. // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
  26. content.close();
  27. }
  28. } catch (OSSException e){
  29. e.printStackTrace();
  30. } catch (IOException e) {
  31. e.printStackTrace();
  32. } finally {
  33. // 关闭OSSClient。
  34. ossClient.shutdown();
  35. }

八、RabbitMQ

1、pom.xml引入amqp依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-amqp</artifactId>
  4. </dependency>

2、applications.properties配置RabbitMQ服务

  1. # RabbitMQ 配置
  2. # RabbitMQ 服务器地址
  3. spring.rabbitmq.host = localhost
  4. # RabbitMQ 端口
  5. spring.rabbitmq.post = 5672
  6. # RabbitMQ 用户
  7. spring.rabbitmq.username = admin
  8. # RabbitMQ 密码
  9. spring.rabbitmq.password = 123456
  10. # 是否确认发送的消息已经被消费
  11. spring.rabbitmq.publisher-confirms = true
  12. #RabbitMQ 的消息队列名称,由它发送字符串
  13. rabbitmq.queue.msg = spring-boot-queue-msg
  14. #RabbitMQ 的消息队列名称,由它发送用户对象
  15. rabbitmq.queue.user = spring-boot-queue-user

3、主启动类使用@EnableRabbit开启功能

4、使用RabbitMQ

(1)使用管理组件AmqpAdmin创建Exchange、Queue、Binding

  1. //1、自动注入
  2. @Autowire
  3. AdqpAdmin amqpAdmin;
  4. //2、创建交换机
  5. DirectExchange directExchange = new DirectExchange($name,$type,$autodelete,$Arg参数);
  6. //3、管理组件声明交换机
  7. amqpAdmin.declareExchange(directExchange);
  8. //4、创建队列
  9. Queue queue = new queue($name,$type,$exclusive,$autodelete,$Arg参数);
  10. //5、管理组件声明队列
  11. amqpAdmin.declareQueue(queue)
  12. //6、创建绑定关系
  13. Binding binding = new Binding($distination,$distinationtype【Distination.Type.Queue or Distination.Type.Exchange】,$exchange,$routingKey,$Arg参数(可null));
  14. //7、管理器声明绑定关系
  15. amqpAdmin.declareBinding(binding);

(2)使用RabbitTemplate收发消息

  1. //1、自动注入
  2. @Autowire
  3. RabbitTemplate rabbitTemplate;
  4. //2、发送消息(如果发送消息是对象,会使用序列化机制,所以对象必须实现Serializable)
  5. rabbitTemplate.convertAndSend($exchange,$routingKey,$object【消息】);
  6. //3、发送对象类型的消息可以是JSON
  7. 需要配置自己的RabbitConfig.java
  8. 给容器中放置消息转换器
  9. @Bean
  10. public MessageConverter messageConverter(){
  11. return new  Jackson2JsonMessageConverter;
  12. }

5、监听RabbitMQ消息

(1)使用@RabbitListener(queues = {"xxx","xxx",…})(必须开启了@EnableRabbit)(可以标注在类或者方法上)

  1. //1、获取消息体(入参Message message,T<发送消息的类型>OrderReturnReasonEntity content,当前传输数据的通道Channel channel)
  2. byte[] body = message.getBody();
  3. JSON.perse();
  4. //2、获取消息头属性信息
  5. MessageProperties = message.getMessageProperties();
  6. //3、Queue中一个消息只能被一个客户端接收,且消息是被有序接收,只有一个消息被处理完才会处理下一个消息

(2)使用@RabbitHandler(可以标注在方法上)(可以重载接收同一队列不同类型消息)

6、Rabbit消息确认机制

(1)【发送端】ConfirmCallback服务收到收到信息回调

        1)开启发送端确认配置application.properties

spring.rabbitmq.publisher-confirms=true

         2)定制rabbitTemplate,设置确认回调

  1. @Autowired
  2. RedisTemplate redisTemplate;
  3. //SpringBoot生成config对象后与执行这个方法
  4. @PostConstruct
  5. public void initRabbitTemplate(){
  6. //设置回调
  7. redisTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback(){
  8. @override
  9. public void confirm(CorrelationData correlationData【唯一Id】, boolean ack【确认】, String cause【原因】){
  10.  
  11. }
  12. });
  13. }

 

(2)【发送端】ReturnCallback消息正确抵达队列进行回调

        1)开启发送端抵达消息队列确认配置application.properties

  1. spring.rabbitmq.publisher-returns=true
  2. # 抵达队列后优先异步执行returns回调确认
  3. spring.rabbitmq.template-mandatory=true

        2)定制rabbitTemplate,没有触发投递队列时,进行回调

  1. @Autowired
  2. RedisTemplate redisTemplate;
  3. //SpringBoot生成config对象后与执行这个方法
  4. @PostConstruct
  5. public void initRabbitTemplate(){
  6. //设置回调
  7. redisTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback(){
  8. @override
  9. public void returnMessage(Message message【投递失败的消息详细信息】, int replayCode【恢复状态码】, String relayText【回复的文本内容】,String exchange【处理的交换机】,String routingKey【消息的路由键】){
  10. }
  11. });
  12. }

(3)消费端确认

第一种方式:默认自动确认的,只要消息接收到,服务端就会移除这个消息

存在问题:收到很多消息消息时,只有一个消息被成功处理,中途宕机,依然确认全部收到删除了队列中数据,造成消息丢失。

第二种方式:手动确认

        1)开启手动确认消息配置application.properties

spring.rabbitmq.listener.simple.acknowledge.-mode=manual

        2)确认签收

  1. long deliveryTag = message.getMessageProperties().getDeliveryTag();
  2. channel.basicAck(deliveryTag, false【不开启批量签收】);

        3)拒收

channel.basicNAck(deliveryTag, false【不开启批量拒收】,true【重新入队】);

九、Sentinel

1、pom.xml引入依赖

  1. <dependency>
  2. <groupId>com.alibaba.cloud</groupId>
  3. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  4. <version>2.1.1.RELEASE</version>
  5. </dependency>

2、通过@SentinelResource配置资源保护规则

  1. @RestController
  2. public class HelloController{
  3. @SentinelResource(value = "hello", blockHandler = "blockHandlerHello")
  4. @GetMapping("/say")
  5. public String hello(){
  6. return "Hello World";
  7. }
  8. //限流保护Controller资源
  9. public String blockHandlerHello(BlockException e){
  10. return "被限流了";
  11. }
  12. }

3、手动配置规则

  1. //可以配置流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则、热点参数规则
  2. public class FlowRuleInitFunc implements InitFunc{
  3. @Override
  4. public void init() throws Exception{
  5. List<FlowRule> rules = new ArrayList<>();
  6. FlowRule rule = new FlowRule();
  7. //限流阈值
  8. rule.setCount(1);
  9. //设置需要保护的资源
  10. rule.setResource("hello");
  11. //流控规则
  12. rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
  13. //针对调用来源限流
  14. rule.setLimitApp("default");
  15. rules.add(rule);
  16. FlowRuleManager.loadRules(rules);
  17. }
  18. }

【限流】

限流的主要目的是通过,限制并发访问 或者 限制一个时间窗口 内允许处理的请求数量,来保护系统,一旦达到限制数量则对当前请求进行处理采取对应的拒绝策略。

  1. private static void initFlowRules(){
  2. List<FlowRule> rules = new ArrayList<>();
  3. FlowRule rule = new FlowRule();
  4. rule.setResource("doSomething");
  5. rule.setCount(20);
  6. rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
  7. rule.setLimitApp("default");
  8. rule.setStrategy(RuleConstant.STRATEGY_CHAIN);
  9. rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
  10. rule.setClusterMode(fasle);
  11. rules.add(rule);
  12. FlowRuleManager.loadRules(rules);
  13. }
  • resource:设置需要保护的资源。
  • count:限流阈值。
  • Grade:限流阈值类型,QPS模式(1)或并发线程数模式(0)。
  • limitApp:是否需要针对调用来源进行限流,默认是default,即不区分调用来源。
  • strategy:调用关系限流策略——直接、链路、关联。
  • controlBehavior:流控行为,包括直接拒绝、排队等待、慢启动模式,默认是直接拒绝。
  • clusterMode:是否是集群限流,默认为否。

【熔断】 

熔断是指当前服务提供者无法正常为服务调用者提供服务时,比如请求超时、服务异常等,为了防止整个系统出现雪崩效应,暂时将出现故障的接口隔离出来,断绝与外部接口的联系,当触发熔断之后,后续一段时间内该服务调用者的请求都会直接失败,知道目标服务恢复正常。

  1. private static void initDegradeRule(){
  2. List<DegradeRule> rules = new ArrayList<>();
  3. DegradeRule degradeRule = new DegradeRule();
  4. degradeRule.setResource("KEY");
  5. degradeRule.setCount(10);
  6. degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
  7. degradeRule.setTimeWindow(10);
  8. degradeRule.setMinRequestAmount(5);
  9. degradeRule.setRtSlowRequestAmount(5);
  10. rules.add(degradeRule);
  11. }
  • grade:熔断策略。支持秒级RT(RuleConstant.DEGRADE_GRADE_RT)、秒级异常比例(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO)、分钟级异常数(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT)。
  • timeWindow:熔断降级的时间窗口,单位s。
  • rtSlowRequestAmount:在RT模式下,1s内持续多少个请求的平均RT超出阈值后触发熔断,默认值是5。
  •  minRequestAmount:触发的异常熔断最小请求数,请求数小于该值时即使异常比例超出阈值也不会触发熔断,默认值是5。

3、基于Sentinel Dashboard配置规则

(1)启动Sentinel Dashboard

(2)在application.yml

  1. spring:
  2. application:
  3. name: spring-cloud-sentinel-sample
  4. cloud:
  5. sentinel:
  6. transport:
  7. dashboard: 192.168.216.128:7777

(3)REST接口

  1. @RestController
  2. public class DashboardController{
  3. @GetMapping("/dash")
  4. public String dash(){
  5. return "Hello Dash";
  6. }
  7. }

 4、自定义URL限流异常

  1. @Service
  2. public class CustomUrlBlockHandler implements UrlBlockHandler{
  3. @Override
  4. public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws IOException {
  5. httpServletResponse.setHeader("Content-Type", "application/json;charset=UTF-8");
  6. String message = "{\"code\":999,\"msg\":\"访问人数过多\"}";
  7. httpServletResponse.getWriter().write(message);
  8. }
  9. }

 降级页面

spring.cloud.sentinel.servlet.block-page={url}

 5、通过UrlCleaner接口实现URL资源清洗

  1. @RestController
  2. public class UrlCleanController{
  3. @GetMapping("/clean/{id}")
  4. public String clean(@PathVariable("id")int id){
  5. return "Hello,Cleaner";
  6. }
  7. }
  1. @Service
  2. public class CustomerUrlCleaner implements UrlCleaner{
  3. @Override
  4. public String clean(String originUrl){
  5. if(StringUtils.isEmpty(originUrl)){
  6. return originUrl;
  7. }
  8. if(originUrl.startsWith("/clean/")){
  9. return "/clean/*";
  10. }
  11. return originUrl;
  12. }
  13. }

 6、集成Nacos实现动态规则同步

 7、Dubbo集成Sentinel

(1)pom.xml添加依赖

  1. <dependency>
  2. <groupId>com.alibaba.csp</groupId>
  3. <artifactId>sentinel-apache-dubbo-adapter</artifactId>
  4. <version>1.7.1</version>
  5. </dependency>

(2)Sentinel Apache Dubbo Adapter自定义开启关闭过滤器

(3)Dubbo服务接入Sentinel Dashboard

        1)引入sentinel-transport-simple-http依赖

  1. <dependency>
  2. <groupId>com.alibaba.csp</groupId>
  3. <artifactId>sentinel-transport-simple-http</artifactId>
  4. <version>1.7.1</version>
  5. </dependency>

        2)添加启动参数

  1. -Djava.net.preferIPv4Stack=true
  2. -Dcsp.sentinel.api.port=8720
  3. -Dcsp.sentinel.dashboard.server=192.168.216.128:7777
  4. -Dproject.name=spring-cloud.sentinel-dubbo.provider

        3)登录Sentinel Dashboard进行簇点链路操作

(4)Dubbo服务限流规则持久化

        1)添加sentinel-datasource-nacos

  1. <dependency>
  2. <groupId>com.alibaba.csp</groupId>
  3. <artifactId>sentinel-datasource-nacos</artifactId>
  4. <version>1.7.1</version>
  5. </dependency>

        2)通过Sentinel提供的InitFunc扩展点,实现Nacos数据源配置

  1. public class NacosDataSourceInitFunc implements InitFunc{
  2. private String serverAddr="192.168.216.128:8848";
  3. private String groupId="DEFAULT_GROUP";
  4. private String dataId="spring-cloud.sentinel-dubbo.provider-sentinel-flow";
  5. @Override
  6. public void init() throws Exception {
  7. loadNacosData();
  8. }
  9. private void loadNacosData(){
  10. ReadableDataSource<String,List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(serverAddr, groupId, dataId, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>(){
  11. }));
  12. FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
  13. }
  14. }

        3)访问Sentinel Dashboard

十、ElasticSearch

Java操作ElasticSearch有两种方式,一个是通过ES的9300端口使用TCP的方式操作,另一种是通过ES的9200端口使用HTTP的方式

1)9300 TCP

spring-data-elasticsearch:transport-api.jar

  • springboot 版本不同, transport-api.jar 不同,不能适配 es 版本

  • 7.x 已经不建议使用,8 以后就要废弃

2)9200 HTTP

  • JestClient:非官方,更新慢

  • RestTemplate:模拟发 HTTP 请求,ES 很多操作需要自己封装,麻烦

  • HttpClient:同上

  • Elasticsearch-Rest-Client:官方 RestClient,封装了 ES 操作,API 层次分明,上手简单

综上所述,选择Elasticsearch-Rest-Client(elasticsearch-rest-high-level-client)是最优的选择,下面记录如何整合

1、pom.xml引入依赖

  1. <dependency>
  2. <groupId>org.elasticsearch</groupId>
  3. <artifactId>elasticsearch</artifactId>
  4. <version>6.3.2</version>
  5. </dependency>
  6. <!-- Java High Level REST Client -->
  7. <dependency>
  8. <groupId>org.elasticsearch.client</groupId>
  9. <artifactId>elasticsearch-rest-high-level-client</artifactId>
  10. <version>6.3.2</version>
  11. </dependency>

2、application.yml配置

  1. elasticsearch:
  2. ip: localhost:9200

3、配置ElasticsearchRestClients

  1. @Configuration
  2. public class ElasticsearchRestClient {
  3. /**
  4. * ES地址,ip:port
  5. */
  6. @Value("${elasticsearch.ip}")
  7. String ipPort;
  8. @Bean
  9. public RestClientBuilder restClientBuilder() {
  10. return RestClient.builder(makeHttpHost(ipPort));
  11. }
  12. @Bean(name = "highLevelClient")
  13. public RestHighLevelClient highLevelClient(@Autowired RestClientBuilder restClientBuilder) {
  14. restClientBuilder.setMaxRetryTimeoutMillis(60000);
  15. return new RestHighLevelClient(restClientBuilder);
  16. }
  17. private HttpHost makeHttpHost(String s) {
  18. String[] address = s.split(":");
  19. String ip = address[0];
  20. int port = Integer.parseInt(address[1]);
  21. return new HttpHost(ip, port, "http");
  22. }
  23. }

4、添加

localhost:9200/customer/_doc/1?pretty
  1. {
  2. "city": "北京",
  3. "useragent": "Mobile Safari",
  4. "sys_version": "Linux armv8l",
  5. "province": "北京",
  6. "event_id": "",
  7. "log_time": 1559191912,
  8. "session": "343730"
  9. }

5、条件查询

  1. @Service
  2. public class TestService {
  3. @Autowired
  4. RestHighLevelClient highLevelClient;
  5. private void search(RestHighLevelClient highLevelClient) throws IOException {
  6. SearchRequest searchRequest = new SearchRequest();
  7. searchRequest.indices("customer");
  8. searchRequest.types("_doc");
  9. // 条件=
  10. MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("city", "北京");
  11. TermQueryBuilder termQuery = QueryBuilders.termQuery("province", "福建");
  12. // 范围查询
  13. RangeQueryBuilder timeFilter = QueryBuilders.rangeQuery("log_time").gt(12345).lt(343750);
  14. SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
  15. QueryBuilder totalFilter = QueryBuilders.boolQuery()
  16. .filter(matchQuery)
  17. .filter(timeFilter)
  18. .mustNot(termQuery);
  19. int size = 200;
  20. int from = 0;
  21. long total = 0;
  22. do {
  23. try {
  24. sourceBuilder.query(totalFilter).from(from).size(size);
  25. sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
  26. searchRequest.source(sourceBuilder);
  27. SearchResponse response = highLevelClient.search(searchRequest);
  28. SearchHit[] hits = response.getHits().getHits();
  29. for (SearchHit hit : hits) {
  30. System.out.println(hit.getSourceAsString());
  31. }
  32. total = response.getHits().totalHits;
  33. System.out.println("测试:[" + total + "][" + from + "-" + (from + hits.length) + ")");
  34. from += hits.length;
  35. // from + size must be less than or equal to: [10000]
  36. if (from >= 10000) {
  37. System.out.println("测试:超过10000条直接中断");
  38. break;
  39. }
  40. } catch (Exception e) {
  41. e.printStackTrace();
  42. }
  43. } while (from < total);
  44. }
  45. }

十一、MySQL

1、pom.xml引入MySQL依赖

  1. <dependency>
  2. <groupId>mysql</groupId>
  3. <artifactId>mysql-connector-java</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-jdbc</artifactId>
  8. </dependency>
  9. <!-- 数据库连接池 -->
  10. <dependency>
  11. <groupId>org.apache.commons</groupId>
  12. <artifactId>commons-dbcp2</artifactId>
  13. </dependency>

2、application.properties

  1. spring.datasource.url=jdbc:mysql://localhost:3306/spring_boot_chapter5
  2. spring.datasource.username=root
  3. spring.datasource.password=123456
  4. # 即使注释掉了驱动,SpringBoot会尽可能判断数据源,然后默认匹配
  5. # spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  6. # 指定数据库连接池类型
  7. spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
  8. # 最大等待连接中的数量,设 0 为没有限制
  9. spring.datasource.dbcp2.max-idle=10
  10. # 最大连接活动数
  11. spring.datasource.dbcp2.max-total=50
  12. # 最大等待毫秒数,单位ms
  13. spring.datasource.dbcp2.max-wait-millis=10000
  14. # 数据库连接池初始化连接数
  15. spring.datasource.dbcp2.initial-size=5

3、使用MyBatis框架

(1)pom.xml引入依赖

  1. <dependency>
  2. <groupId>org.mybatis.spring.boot</groupId>
  3. <artifactId>mybatis-spring-boot-starter</artifactId>
  4. <version>1.3.1</version>
  5. </dependency>

(2)application.properties

  1. # MyBatis映射文件通配
  2. mybatis.mapper-locations=classpath:com/springboot/chapter/mapper/*.xml
  3. # Mybatis扫描别名包,和注解@Alias联用
  4. mybatis.type-aliases-package=com.springboot.chapter.pojo
  5. # 配置typeHandler的扫描包
  6. mybatis.type-handlers-package=com.springboot.chapter.typehandler

可配置属性

  1. properties :属性
  2. settings:设置
  3. typeAliases:类型别名
  4. typeHandlers:类型处理器
  5. objectFactory:对象工厂
  6. plugins:插件
  7. environments:数据库环境
  8. databaseIdProvider:数据库厂商标识
  9. mappers:映射器

(3)使用@Mapper注解表示Mapper(Dao)接口

(4)启动类使用@MapperScan()扫描

十二、Redis

1、pom.xml引入Redis依赖

  1. <!-- 引入Redis的客户端驱动 -->
  2. <dependency>
  3. <groupId>redis.clients</groupId>
  4. <artifactId>jedis</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-redis</artifactId>
  9. <exclusions>
  10. <exclusion>
  11. <groupId>io.lettuce</groupId>
  12. <artifactId>lettuce-core</artifactId>
  13. </exclusion>
  14. </exclusions>
  15. </dependency>

2、application.properties

  1. # 配置连接池属性
  2. spring.redis.jedis.pool.min-idle=5
  3. spring.redis.jedis.pool.max-idle=10
  4. spring.redis.jedis.pool.max-active=10
  5. spring.redis.jedis.pool.max-wait=2000
  6. # 配置Redis服务器属性
  7. spring.redis.port=6379
  8. spring.redis.host=192.168.11.131
  9. spring.redis.password=123456
  10. # Redis连接超时时间,单位ms
  11. spring.redis.timeout=1000

3、使用springboot提供的StringRedisTemplate来操作redis(是对jedis的再次封装)

  1. ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
  2. //保存
  3. ops.set("hello", "world_" + UUID.randomUUID().toString());
  4. //查询
  5. String hello = ops.get("hello");

十三、MongoDB

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/165681
推荐阅读
相关标签
  

闽ICP备14008679号