二言目 - Spring Cloud
type: channel
link: https://blog.piemoe.com/tag/SpringCloud/
items: 使用SpringCloud Alibaba结合Springboot3.0 搭建一个demo
items: 通过注解或Lambda方式进行数据脱敏
items: 自制Redis的Sringboot Starter
items: openFeign远程调用
items: nacos作为配置中心
items: nacos作为注册中心
items: SpringCloud 学习笔记 05 --openFeign
items: SpringCloud 学习笔记 04 --ribbon
items: SpringCloud 学习笔记 02 --zookeeper
items: SpringCloud 学习笔记 03 --consul

使用SpringCloud Alibaba结合Springboot3.0 搭建一个demo
type: item
date: 2023-02-17T12:51:00+08:00
description: Springboot 3 出来也有一段时间了，Springcloud alibaba也在适配当中，本demo使用Springboot 3 + Spingcloud alibaba + nacos等组件，完成一个项目工程的简单搭建组件Nacos : 2.0.3Maven：3.0.8依赖版本springboot :3.0.4springcloud:2022.0.1springcloud alibaba :2.2.10-RC1spring-cloud-starter-alibaba-nacos-discovery:2022.0.0.0-RC1spring-cloud-starter-alibaba-nacos-config：2022.0.0.0-RC1springcloud alibaba 2.2.10-RC1 版本提供的Nacos依赖，经测试无法成功注册，故使用2022.0.0.0-RC1版本项目POM<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.0.4</version> <relativePath/> </parent> <groupId>com.piemoe</groupId> <artifactId>springboot3</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot3</name> <description>springboot3</description> <properties> <java.version>17</java.version> </properties> ​ <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2022.0.1</version> <type>pom</type> <scope>import</scope> </dependency> ​ <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.10-RC1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ​ <dependencies> ​ <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dep…

通过注解或Lambda方式进行数据脱敏
type: item
date: 2022-11-10T10:51:00+08:00
description: 前言数据脱敏是一种数据保护技术，它可以对敏感数据进行处理，使其失去原始意义，从而保护数据隐私。通俗地说，就是将原始数据中敏感信息的部分替换或删除，例如：手机号码中的一部分数字替换为星号，或是姓名中的一些字母用其他字母代替等等。数据脱敏可以保护个人隐私，防止个人信息被泄露、滥用，同时也符合现代法律法规对个人信息保护的要求，是网络安全和信息保护中不可或缺的一环。本文将通过使用注解完成对字段的自定义脱敏功能。正文本文将介绍2种脱敏的方式，分别为：注解方式脱敏和lambda方式脱敏注解脱敏定义脱敏注解@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @JacksonAnnotationsInside @JsonSerialize(using = SensitiveSerialize.class) public @interface Dm { /** * 脱敏信息类型 */ DmTypeEnum type(); /** * 前置不需要打码的长度 * 只有 {@link DmTypeEnum} 为 {@link DmTypeEnum#CUSTOMER} 时可用 */ int prefixNoMaskLen() default 0; /** * 后置不需要打码的长度 * 只有 {@link DmTypeEnum} 为 {@link DmTypeEnum#CUSTOMER} 时可用 */ int suffixNoMaskLen() default 0; /** * 用什么打码 * 只有 {@link DmTypeEnum} 为 {@link DmTypeEnum#CUSTOMER} 时可用 */ char symbol() default '*'; }type()方法为可以支持实现的脱敏信息类型，通过使用hutool工具，可以看到它支持以下枚举，故拉取出来形成类型枚举：public enum DmTypeEnum { /** * 用户自定义 */ CUSTOMER, /** * 用户id */ BACK_ID, /** * 中文名 */ CHINESE_NAME, /** * 身份证号 */ ID_CARD, /** * 座机号 */ FIXED_PHONE, /** * 手机号 */ MOBILE_PHONE, /** * 地址 */ ADDRESS, /** * 电子邮件 */ EMAIL, /** * 密码 */ PASSWORD, /** * 中国大陆车牌，包含普通车辆、新能源车辆 */ CAR_LICENSE, /** * 银行卡 */ BANK_CARD }关键语句在@JsonSerialize(using = SensitiveSerialize.class)上，@JsonSerialize 是一个注解，它可以用来指定 Java 对象序列化成 JSON 格式时的序列化规则。具体而言，它可以指定序列化时属性名的命名方式、日期格式化等等。它的作用是使得 Java 对象可以方便地转化为 JSON 格式，这对于 Web 开发、移动应用开发等场景非常有用，故此我们在这里自定义一个实现，并在注解中引用。@NoArgsConstructor @AllArgsConstructor @Slf4j public class SensitiveSerialize<T> extends JsonSerializer<T> implements ContextualSerializer { /** * 脱敏类型 */ private DmTypeEnum sensitiveTypeEnum; /** * 前几位不脱敏 */ private Integer prefixNoMaskLen; /** * 最后几位不脱敏 */ private Integer suffixNoMaskLen; /** * 打码字符 */ private char symbol; @Override public void serialize(final T value, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException { Object desensitized = DmUtils.desensitized(value.toString(), sensitiveTypeEnum, prefixNoMaskLen, suffixNoMaskLen, symbol); if (desensitized instanceof String) { jsonGene…

自制Redis的Sringboot Starter
type: item
date: 2022-01-18T09:25:00+08:00
description: 前言springcloud项目通常会遇到以下2个问题：配置项目redis组件时，有时会遇到一些序列化的问题，如当使用jackson的时，使用@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)注解，会报这个实体不是一个数组的问题集成通用redis依赖组件，可以让所有的项目共同依赖默认一个redis过期时间，更好的利用redis资源正文项目依赖Springboot : 2.6.3Springcloud: 2021.0.1Springcoud Alibaba: 2021.0.1.0redis依赖<?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"> <parent> <artifactId>framework-common</artifactId> <groupId>com.xxx</groupId> <version>2.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> ​ <artifactId>framework-common-redis</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> </dependencies> </project>配置redis序列@Configuration @AutoConfigureBefore(RedisAutoConfiguration.class) public class BaseRedisConfig { ​ @Bean @ConditionalOnMissingBean(name = "redisTemplate") public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); redisTemplate.setKeySerializer(RedisSerializer.string()); redisTemplate.setHashKeySerializer(RedisSerializer.string()); redisTemplate.setValueSerializer(RedisSerializer.json()); redisTemplate.setHashValueSerializer(RedisSerializer.json()); return redisTemplate; } ​ } ​ /** * redis 默认缓存时间 */ @Bean public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); //设置Redis缓存有效期为7天 RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() // 使的reids注解缓存的key中 "::"2个冒号转换成":"一个冒号，统一redis key的风格 .computePrefixWith(name -> name + ":") .serializeValuesWith(RedisSerializationContext.Serializ…

openFeign远程调用
type: item
date: 2019-04-22T12:45:00+08:00
description: 1.服务生产方生产方方法示例@RequestMapping("/member/list") public R memberCoupon(){ CouponEntity couponEntity = new CouponEntity(); couponEntity.setCouponName("满一百减十"); return R.ok().put("coupons", Collections.singletonList(couponEntity)); }2.服务消费方2.1引入openfeign2.1.1 springbootApplication.java开启远程调用@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class GulimallMemberApplication { public static void main(String[] args) { SpringApplication.run(GulimallMemberApplication.class, args); } }2.1.2 创建接口编写一个接口，告诉 springcloud 这个接口需要远程服务@FeignClient("gulimall-coupon") 其中，gulimall-coupon 为被调用的服务名——spring.applicaiton.name@FeignClient("gulimall-coupon") //调用的服务名 public interface CouponFeignService { @RequestMapping("/coupon/coupon/member/list") public R memberCoupon(); }3.结果http://localhost:8000/member/member/coupons

nacos作为配置中心
type: item
date: 2019-04-21T16:52:00+08:00
description: 0.优先级配置中心>本地1.pom<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>2.application.ymlspring: application: name: gulimall-coupon cloud: nacos: discovery: server-addr: http://nacos.chaospring.com/3. bootstrap.properties使用 bootstrap.properties 配置文件来配置Nacos Server 地址spring.application.name=gulimall-coupon #80端口不能省略 spring.cloud.nacos.config.server-addr=http://nacos.chaospring.com:804.controller使用 @RefreshScope 注解刷新@RefreshScope使用 @Value 获取配置内容@Value("${coupon.user.name}") private String name; @Value("${coupon.user.age}") private Integer age; @RequestMapping("/test") public R test() { return R.ok().put("name", name).put("age", age); }5.nacos配置若指定了开发环境，则名字为：gulimall-coupon-dev.properties6.环境配置隔离命名空间：配置隔离6.1新增命名空间6.2作用可以利用命名空间做环境隔离bootstrap.properties 下添加配置#命名空间 spring.cloud.nacos.config.namespace=68e1547d-d96c-4794-bbb5-de2061b135917.服务配置隔离7.1每个微服务创建一个命名空间7.2配置集配置集：所有的配置集合DataID:类似文件名配置分组：默认所有的配置集都属于：DEFAULT_GROUPbootstrap.properties 下添加配置spring.cloud.nacos.config.group=dev7.3拆分配置文件的配置集bootstrap.properties 下添加配置spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yml spring.cloud.nacos.config.extension-configs[0].group=dev #是否动态刷新 默认是false spring.cloud.nacos.config.extension-configs[0].refresh=true spring.cloud.nacos.config.extension-configs[1].data-id=mybatis.yml spring.cloud.nacos.config.extension-configs[1].group=dev spring.cloud.nacos.config.extension-configs[1].refresh=true spring.cloud.nacos.config.extension-configs[2].data-id=other.yml spring.cloud.nacos.config.extension-configs[2].group=dev spring.cloud.nacos.config.extension-configs[2].refresh=true.问题nacos配置中心超时问题：java.net.ConnectException: no available server, currentServerAddr单独指定 nacos-client 版本<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.0.RELEASE</version> <type>pom</type> <scope>import</scope> <exclusions> <exclusion> <groupId>com.alibaba.na…

nacos作为注册中心
type: item
date: 2019-04-21T12:35:00+08:00
description: 1.依赖父pom<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.2.6.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR3</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <addResources>true</addResources> </configuration> </plugin> </plugins> </build>子pom <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>2.application.ymlspring: application: name: xxx-coupon cloud: nacos: discovery: #域名末尾要加 / server-addr: http://nacos.chaospring.com/ management: endpoints: web: exposure: include: '*'3.springbootApplication.class@SpringBootApplication @EnableDiscoveryClient //注册注解 public class springbootApplication { public static void main(String[] args) { SpringApplication.run(GulimallCouponApplication.class, args); } }

SpringCloud 学习笔记 05 --openFeign
type: item
date: 2018-03-25T16:13:00+08:00
description: openFeign是一个声明式的Web 服务客户端，让编写Web服务客户端变得非常容易，只需创建一个借口并在借口上添加注解即可。用于服务调用方1.pom<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>com.atguigu.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</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-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>2.application.ymlserver: port: 80 spring: application: name: cloud-consumer-feign-order #设置feign客户端超时时间(OpenFeign默认支持ribbon) ribbon: #指的是建立连接所用的时间，适用于网络状况正常的情况下,两端连接所用的时间 ReadTimeout: 5000 #指的是建立连接后从服务器读取到可用资源所用的时间 ConnectTimeout: 5000 logging: level: # feign日志以什么级别监控哪个接口 org.mc.mycloud.service.PaymentFeignService: debug eureka: client: #表示是否将自己注册进EurekaServer默认为true。 register-with-eureka: true #是否从EurekaServer抓取已有的注册信息，默认为true。单节点无所谓，集群必须设置为true才能配合ribbon使用负载均衡 fetchRegistry: true service-url: #单机版 # defaultZone: http://localhost:7001/eureka # 集群版 defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #主机名称 服务修改 instance: instance-id: order80 #访问路径可以显示IP地址 prefer-ip-address: true # #Eureka客户端向服务端发送心跳的时间间隔，单位为秒(默认是30秒) # #lease-renewal-interval-in-seconds: 1 # #Eur…

SpringCloud 学习笔记 04 --ribbon
type: item
date: 2018-03-25T13:45:00+08:00
description: 1.自定义ribbon 查询机制目录结构：org--mc----mycloud------OrderMain80.java //主启动类----myrule------MyRibbonRule.java //不能和主启动类在一个包或其子包下a.自定义MyRibbonRule.java@Configuration public class MyRibbonRule { @Bean public IRule myRule(){ return new RandomRule(); //随机规则 } }b.主启动类@SpringBootApplication @EnableEurekaClient @RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MyRibbonRule.class) //修改默认的ribbon规则 public class OrderMain80 { public static void main(String[] args) { SpringApplication.run(OrderMain80.class, args); } }ribbon 包括了 restTemplate 是restTemplate 的增强。

SpringCloud 学习笔记 02 --zookeeper
type: item
date: 2018-03-24T15:59:00+08:00
description: SpringCloud 学习笔记 02 --zookeeperSpringCloud 学习笔记 02 --zookeeper1. docker搭建zookeeper环境：centOS7a. 拉取 zookeeper 镜像docker pull zookeeperb. 部署1.将它部署在 /usr/local/zookeeper 目录下：cd /usr/local && mkdir zookeeper && cd zookeeper2.创建data目录，用于挂载容器中的数据目录：mkdir data3.部署命令docker run -d -e TZ="Asia/Shanghai" -p 2181:2181 -v $PWD/data:/data --name zookeeper --restart always zookeeper-e TZ="Asia/Shanghai" # 指定上海时区 -d # 表示在一直在后台运行容器 -p 2181:2181 # 对端口进行映射，将本地2181端口映射到容器内部的2181端口 --name # 设置创建的容器名称 -v # 将本地目录(文件)挂载到容器指定目录； --restart always #始终重新启动zookeeper查看容器启动情况：docker ps -a4.连接使用zk命令行客户端连接zkdocker run -it --rm --link zookeeper:zookeeper zookeeper zkCli.sh -server zookeeper说明：-server zookeeper是启动zkCli.sh的参数5.其他命令# 查看zookeeper容器实例进程信息 docker top zookeeper # 停止zookeeper实例进程 docker stop zookeeper # 启动zookeeper实例进程 docker start zookeeper # 重启zookeeper实例进程 docker restart zookeeper # 查看zookeeper进程日志 docker logs -f zookeeper # 杀死zookeeper实例进程 docker kill -s KILL zookeeper # 移除zookeeper实例 docker rm -f -v zookeeperc. 集群方式安装1.安装docker-composecurl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose2.配置docker-compose编写配置文件，并将其命名为：docker-compose.yml（docker-compose默认配置文件名）配置文件内容：version: '2' services: zoo1: image: zookeeper restart: always container_name: zoo1 ports: - "2181:2181" environment: ZOO_MY_ID: 1 ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888 zoo2: image: zookeeper restart: always container_name: zoo2 ports: - "2182:2181" environment: ZOO_MY_ID: 2 ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888 zoo3: image: zookeeper restart: always container_name: zoo3 ports: - "2183:2181" environment: ZOO_MY_ID: 3 ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888此配置文件表示，Docker需要启动三个zookeeper实例，并将2181，2182，2183三个端口号映射到容器内的2181这个端口上。ZOO_MY_ID：表示zk服务的ID, 取值为1-255之间的整数，且必须唯一ZOO_SERV…

SpringCloud 学习笔记 03 --consul
type: item
date: 2018-03-24T15:56:00+08:00
description: 1.win10使用consula.官网下载地址b.安装使用教程c.使用方法2.Linux使用consul3.服务提供者子模块a.pom<dependencies> <dependency> <groupId>com.atguigu.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>RELEASE</version> <scope>test</scope> </dependency> </dependencies>b.applicaiton.yml###consul服务端口号 server: port: 8006 spring: application: name: consul-provider-payment ####consul注册中心地址 cloud: consul: host: localhost port: 8500 discovery: #hostname: 127.0.0.1 service-name: ${spring.application.name}c.主启动@SpringBootApplication @EnableDiscoveryClient //用于zookeeper 和 consul 服务发现 public class ConsulMain8006 { public static void main(String[] args) { SpringApplication.run(ConsulMain8006.class, args); } }d.流程代码@RestController public class PaymentController { @Value("${server.port}") private String serverPort; @RequestMapping("/payment/consul") public String paymentConsul() { return "springCloud whit consul:" + serverPort + "\t" …