irpas技术客

(二)学习spring-cloud:2021_依旧为殇_springcloud2021

irpas 7403

1. 前言

1.1 为啥要使用spring-cloud:2021.0.x?

????????原先使用Hoxton.SR8版本的springcloud,由于Netflix公司宣布其核心组件Hystrix、Ribbon、Zuul、Eureka等进入维护状态,不再进行新特性开发,只修 BUG。而spring官方因此做出应对,在新版本中移除了Netflix,顺便学习下新版本cloud,因此使用最新版本的cloud。

2.项目迭代历程

以springboot搭建spring-authorization-server(即认证与资源服务器)

升级为springcloud2021.0.x框架,引入nacos作为注册中心

引入sentinel,进行限流降级熔断配置

引入nacos配置中心

升级sentinel,配合nacos,使项目能动态配置落地所有Feign的降级配置

引入gateway网关,swagger文档工具

待续

3.项目构建

3.1 认证服务器升级

????????pom.xml引入cloud相关依赖

<!--Spring Cloud Alibaba 相关依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2021.0.1.0</version> <type>pom</type> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2021.0.1.0</version> </dependency>

????????增加application.yml对nacos的配置

spring: cloud: nacos: discovery: server-addr: 192.168.1.69:8848

????????新建controler,提供feign接口

@Slf4j @RestController public class ServerController { @GetMapping("/getServerTest") public SingleResultBundle<String> getServerTest(){ return SingleResultBundle.success("这是resource的测试方法 getResourceTest()"); } } 3.2?资源服务器升级

????????pom.xml引入cloud相关依赖

<!-- 测试的feign模块 --> <dependency> <groupId>com.xueliman.iov</groupId> <artifactId>server-feign</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2021.0.1.0</version> <type>pom</type> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2021.0.1.0</version> </dependency>

????????增加application.yml对nacos的配置

spring: cloud: nacos: discovery: server-addr: 192.168.1.69:8848

????????启动类 ResourceApplication 增加相关注解

// 可以扫描到相关目录下含FeignClient的包 @EnableFeignClients(basePackages = {"com.xxxx.**"}) // 这个好像可以不要 @EnableDiscoveryClient

????????新增Controller进行feign调用接口测试

@Slf4j @RestController public class UserServerController { @Autowired private ServerFeign serverFeign; @GetMapping("/getServerTest") public SingleResultBundle<String> getServerTest(){ return serverFeign.getServerTest(); } } 3.3?新建server-feign模块

????????此模块作为server认证服务器的feign模块,进行测试feign调用,因此需要开启认证服务器server中校验部分

???????修改server模块中WebSecurityConfig类

@Bean public SecurityFilterChain httpSecurityFilterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity .authorizeRequests(authorizeRequests -> authorizeRequests.antMatchers("/login").permitAll() .anyRequest().authenticated() ) //使用默认登录页面 //.formLogin(withDefaults()) //设置form登录,设置且放开登录页login .formLogin(fromlogin -> fromlogin.loginPage("/login").permitAll()) // Spring Security CSRF保护 .csrf(csrfToken -> csrfToken.csrfTokenRepository(new CookieCsrfTokenRepository())) //开启认证服务器的资源服务器相关功能,即需校验token .oauth2ResourceServer() .accessDeniedHandler(new SimpleAccessDeniedHandler()) .authenticationEntryPoint(new SimpleAuthenticationEntryPoint()) .jwt() ; return httpSecurity.build(); } }

????????新建Feign的配置类 FeignRequestConfig

/** * 为解决调用feign接口,需要认证服务 * 因此实现RequestInterceptor,对feign接口进行拦截,使其request中的header头部添加上token参数 * @author zxg */ @Slf4j @Configuration public class FeignRequestConfig implements RequestInterceptor { @Override public void apply(RequestTemplate template) { HttpServletRequest httpServletRequest = getHttpServletRequest(); if(httpServletRequest!=null){ Map<String, String> headers = getHeaders(httpServletRequest); // 传递所有请求头,防止部分丢失 //此处也可以只传递认证的header //requestTemplate.header("Authorization", request.getHeader("Authorization")); for (Map.Entry<String, String> entry : headers.entrySet()) { template.header(entry.getKey(), entry.getValue()); } log.debug("FeignRequestInterceptor:{}", template.toString()); } } private HttpServletRequest getHttpServletRequest() { try { return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); } catch (Exception e) { return null; } } /** * 获取原请求头 */ private Map<String, String> getHeaders(HttpServletRequest request) { Map<String, String> map = new LinkedHashMap<>(); Enumeration<String> enumeration = request.getHeaderNames(); if(enumeration!=null){ while (enumeration.hasMoreElements()) { String key = enumeration.nextElement(); String value = request.getHeader(key); map.put(key, value); } } return map; } }

????????新建feign接口 ServerFeign

@FeignClient(name = "server", fallbackFactory = ServerFeign.ServerFallback.class, configuration = FeignRequestConfig.class) public interface ServerFeign { @GetMapping(value = "/getServerTest") SingleResultBundle<String> getServerTest(); @Slf4j @Component class ServerFallback implements FallbackFactory<ServerFeign> { @Override public ServerFeign create(Throwable cause) { return new ServerFeign() { @Override public SingleResultBundle<String> getServerTest() { log.warn("远程调用被限流/降级了", cause); return SingleResultBundle.failed("接口请求异常"); } }; } } } 3.4?测试项目

????????分别启动server,resource服务。使用postman测试接口,结果返回如下

4.总结

????????升级为cloud,仅需引入对应cloud依赖,注意cloud版本之间是否兼容。以及使用feign接口调用时,注意要带上token,即上文中我们的配置的FeignRequestConfig文件,会将头部的token带过去。

????????期间在网上搜寻了很多资料,然后进行整合,因此文中存在与其他网上教程相同代码,如有争议,请联系我删除改正,谢谢。由于不太会写文章,我就直接贴出代码,代码中我有加上注释,所以上述文章中,没有很具体的描述,基本就是个人开发流程,若文中有那里写不对,欢迎指教,不喜勿喷。

? ? ? ? 后续整合sentinel部分,请关注后续文章


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #springcloud2021 #1 #前言11 #BUG