网易首页 > 网易号 > 正文 申请入驻

Spring Cloud 与响应式微服务

0
分享至

官方网站 www.itilzj.com 文档资料: wenku.itilzj.com

众所周知,Spring Cloud 服务间的调用方式是使用的 RESTful API,我们平时都是R estTemplate 或 Feign 来调用的,这两种方式其实说到底都是同步的方式。

Spring 支持响应式编程。那么我们能不能在 Spring Cloud 的服务间调用的时候用这种异步非阻塞的方式呢?随着 Spring Cloud Finchley 的发布,这一切均可以实现。

本文我们就用 WebFlux、Spring Data Reactive 从头到脚构建一个响应式的微服务。

准备

为了完成这个示例,我们需要:

  • 一个服务注册中心

  • 两个微服务

  • 一个数据库

服务注册中心:我们要用到服务发现和服务注册,这里用一个单节点的 Eureka Server来做。

两个微服务:帐户服务和客户服务。每个微服务都有自己的数据库,且对外暴露简单的响应式 API,用于检索和存储数据。另外,客户服务与帐户服务可以相互通信,以获取客户的所有帐户,并通过客户服务 API 方法返回。

数据库:因为现在还没几个数据库有实现了反应式数据访问的可用驱动,Spring Data Reactive 目前仅支持 MangoDB、Redis 和 Cassandra,简单起见我们就用 MangoDB。MangoDB 我这里使用 Docker 来创建,一切均用默认配置(主要是懒 ,这样就不用去改 Spring Boot 的配置文件了)

docker run -d --name mongo -p 27017:27017 mongo

实战

服务注册中心

新建一个基本的 Spring Boot 工程,命名为eureka-server。

pom.xml 中依赖如下:

org.springframework.cloudgroupId>spring-cloud-starter-netflix-eureka-serverartifactId>dependency>

配置文件 application.yml 配置如下:

spring:application:name: eureka-servereureka:client:register-with-eureka: falsefetch-registry: falseservice-url:defaultZone: http://localhost:8000/eureka/server:port: 8000

在启动类上加上 @EnableEurekaServer 注解:

@EnableEurekaServer@SpringBootApplicationpublic class EurekaServerApplication {
public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class, args);}}

账户服务

新建一个基本的 Spring Boot 工程,命名为 cloud-account。

如果是使用 Spring Initializr 话,引入 Lombok、Reactive Web、Reactive MongoDB 和 Eureka Discovery 这四个依赖。

最终 pom.xml 中应有以下依赖:

org.springframework.bootgroupId>spring-boot-starter-data-mongodb-reactiveartifactId>dependency>org.springframework.bootgroupId>spring-boot-starter-webfluxartifactId>dependency>org.springframework.cloudgroupId>spring-cloud-starter-netflix-eureka-clientartifactId>dependency>org.projectlombokgroupId>lombokartifactId>trueoptional>dependency>io.projectreactorgroupId>reactor-testartifactId>testscope>dependency>

配置文件 application.yml

spring:application:name: cloud-accountserver:port: 8100eureka:client:service-url:defaultZone: http://localhost:8000/eureka/

创建账户的实体类,其中 @AllArgsConstructor、@NoArgsConstructor 和 @Data 都是 Lombok 提供注解,不了解的可以自行学习,这里不多说了。

@AllArgsConstructor@NoArgsConstructor@Data@Document(collection = "accounts")public class Account {@Idprivate String id;private String customerId;private Double amount;}

我们使用 Spring Data Reactive。与非响应式 Spring Data 的 CrudReposity 对应的,响应式的 Spring Data 也提供了相应的 Repository 库:ReactiveCrudReposity,我们也可以使用它的子接口 ReactiveMongoRepository。

public interface AccountMongoReactiveRepository extends ReactiveCrudRepository {Flux findByCustomerId (String customerId) ;}

为账户服务创建对应的 Controller,这里只简单提供一个查询客户的所有账户的接口。为了在后面测试负载均衡,这里加上了调用时间戳的打印。

@RequestMapping("/account")@RestControllerpublic class AccountController {
@Autowiredprivate AccountMongoReactiveRepository repository;
@GetMapping("/customer/{customer}")public Flux findByCustomer( @PathVariable(name = "customer") String customer) {System.out.println("Customer => " + customer + " [ " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss.SSS")) + " ]");return repository.findByCustomerId(customer);}
}

客户服务

新建一个基本的 Spring Boot 工程,命名为cloud-customer,POM 依赖和之前的cloud-account 的一模一样。

配置文件如下,仅是改了服务名和端口号:

spring:application:name: cloud-customerserver:port: 8200eureka:client:service-url:defaultZone: http://localhost:8000/eureka/

创建一个 Customer 的实体类:

@Data@AllArgsConstructor@NoArgsConstructor@Document(collection = "customers")public class Customer {@Idprivate String id;private String name;private String mobile;}

数据访问层直接继承 ReactiveCrudRepository,我们便有了基本的 CRUD 能力:

public interface CustomerMongoReactiveRepository extends ReactiveCrudRepository {}

因为我们只是示例,不做复杂的业务逻辑,所以省略了 Service 层,在 Controller 里边直接将 CRUD 的操作代理给了 Repository。

@RestController@RequestMapping("/customer")public class CustomerController {
@Autowired private CustomerMongoReactiveRepository repository;@Autowired private WebClient.Builder webClientBuilder;
@GetMapping("")public Flux list() {return repository.findAll();}
@GetMapping("/{id}")public Mono get( @PathVariable String id) {return repository.findById(id);}
@PostMapping("")public Mono create( @RequestBody Customer customer) {return repository.save(customer);}
@PutMapping("/{id}")public Mono update( @PathVariable("id") String id, @RequestBody Customer customer) {customer.setId(id);return repository.save(customer);}
@DeleteMapping("/{id}")public Mono delete(@PathVariable String id) {return repository.deleteById(id);}
}

到这里,我们的服务注册中心和两个微服务就都好了。但是,这两个微服务之间还是完全独立的,没有相互间的服务调用。现在我们来实现之前说的需求:客户服务与帐户服务可以相互通信,以获取客户的所有帐户,并通过客户服务 API 方法返回。

首先创建一个 Java Config,这里我们不再使用 RestTemplate 来调用服务,而是WebClient。这个配置看起来和注册 RestTemplate 时差不多,但是要注意这里注册的 Bean 是WebClient.Builder。

@Configurationpublic class WebClientConfig {
@Bean@LoadBalancedpublic WebClient.Builder loadBalancedWebClientBuilder() {return WebClient.builder();}
}

除了这种写法,还有一种写法是:

public class MyClass {@Autowiredprivate LoadBalancerExchangeFilterFunction lbFunction;
public Mono doOtherStuff() {return WebClient.builder().baseUrl("http://cloud-account/account").filter(lbFunction).build().get().uri("").retrieve().bodyToMono(String.class);}}

下边的是错误的写法,会抛出异常:

@Bean@LoadBalancedpublic WebClient loadBalancedWebClient() {return WebClient.builder().baseUrl("http://cloud-account/account").build();}

然后在 CustomerController 实现这个端点:

@GetMapping("/{id}/account")public Flux getAllAccounts( @PathVariable String id) {return webClientBuilder.baseUrl("http://cloud-account/account/").build().get().uri("/customer/" + id).retrieve().bodyToFlux(Account.class);}

这里需要在 cloud-customer 里创建一个 DTO Account,因为和 cloud-account 里的完全一样,就省略了。



测试

同时启动两个 cloud-account 服务:

然后不断请求 http://localhost:8200/customer/5ae15fa640f1687f200d8941/account 接口,从下图的时间戳可以看出 WebClient 会轮流请求两个服务,达到了负载均衡的效果。

总结

我们从服务提供、服务调用、数据访问三个方面均使用了响应式编程(Reactive Programming),可以说是做到了 Full Reactive Stack Backend。相信你对响应式编程及其在 Web 应用、微服务架构中如何发挥作用有了更多的体会,本文实战是比较基础的,因为切换到响应式思维方式并非易事,希望能够通过上手编写代码体会响应式编程的感觉。

IT架构师/技术大咖的交流圈子,为您提供架构体系知识、技术文章、流行实践案例、解决方案等,行业大咖分享交流/同行经验分享互动,期待你的加入!扫码即可加入哦,随着材料不断增多社群会不定期涨价早加入更优惠

免责声明:

本公众号部分分享的资料来自网络收集和整理,所有文字和图片版权归属于原作者所有,且仅代表作者个人观点,与本公众号无关,文章仅供读者学习交流使用,并请自行核实相关内容,如文章内容涉及侵权,请联系后台管理员删除

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
河南叶县一冷藏车违规载人致8人窒息死亡,村民:其中3名女工同村,都在肉类加工厂打工

河南叶县一冷藏车违规载人致8人窒息死亡,村民:其中3名女工同村,都在肉类加工厂打工

极目新闻
2024-06-17 13:49:25
宝马男和网恋女友奔现,发现女友只有20岁,男子:给你一万回家去

宝马男和网恋女友奔现,发现女友只有20岁,男子:给你一万回家去

百晓史
2024-06-17 08:34:05
贵州省红十字会原党组书记王开禄,被“双开”

贵州省红十字会原党组书记王开禄,被“双开”

新京报
2024-06-17 11:30:32
阿里数赛全球第1名,被大家忽略的徐啸宇,到底有多优秀?

阿里数赛全球第1名,被大家忽略的徐啸宇,到底有多优秀?

冒泡泡的鱼儿
2024-06-15 10:35:02
ASML掀老底:3nm芯片实际为23nm,1nm芯片是18nm?

ASML掀老底:3nm芯片实际为23nm,1nm芯片是18nm?

互联网.乱侃秀
2024-06-16 14:14:18
郭有才再受沉重打击,榜一大哥宣布退网,曾给他刷几百万礼物

郭有才再受沉重打击,榜一大哥宣布退网,曾给他刷几百万礼物

新游戏大妹子
2024-06-16 12:04:51
银行人员透露:今明两年,最好不要把钱存定期,这两个原因很现实

银行人员透露:今明两年,最好不要把钱存定期,这两个原因很现实

开心体育站
2024-06-16 15:50:08
董宇辉直播引发大量投诉!官方回应

董宇辉直播引发大量投诉!官方回应

鲁中晨报
2024-06-17 06:43:05
刚跟中国签完中吉乌铁路,扭脸从韩国买高铁,中亚国家举动引关注

刚跟中国签完中吉乌铁路,扭脸从韩国买高铁,中亚国家举动引关注

影孖看世界
2024-06-16 20:47:44
战略负担:俄罗斯正“失去”克里米亚!成为烫手山芋

战略负担:俄罗斯正“失去”克里米亚!成为烫手山芋

项鹏飞
2024-06-12 16:34:13
没有对比就没有伤害,如果换他们来演庄国栋,彭冠英就不会被骂了

没有对比就没有伤害,如果换他们来演庄国栋,彭冠英就不会被骂了

温柔娱公子
2024-06-16 18:02:56
昔日山东知名主持人张敏健

昔日山东知名主持人张敏健

综艺拼盘汇
2024-06-17 07:30:13
玩家在垃圾桶内捡到粉色限定PS2:竟还能正常工作

玩家在垃圾桶内捡到粉色限定PS2:竟还能正常工作

游民星空
2024-06-16 19:05:14
路易小王子在庆典上表情包又火了!差点抢了凯特风头,还打哈欠呢

路易小王子在庆典上表情包又火了!差点抢了凯特风头,还打哈欠呢

时尚丽人风行
2024-06-16 10:16:45
去年中国汽车品牌销量首次超越美国,仅次于日欧

去年中国汽车品牌销量首次超越美国,仅次于日欧

界面新闻
2024-06-17 12:20:40
上海这夜,耍大牌周也和勒肉张碧晨,都败给了“全裹”出镜的高叶

上海这夜,耍大牌周也和勒肉张碧晨,都败给了“全裹”出镜的高叶

一娱三分地
2024-06-16 08:55:03
看右边是谁?以前他瘦时看习惯了这冷不丁发福点乍一眼还没看出来

看右边是谁?以前他瘦时看习惯了这冷不丁发福点乍一眼还没看出来

牛叨小史
2024-06-17 10:36:46
中国人不骗中国人,TikTok上建盏开窑直播间忽悠老外,评论笑死

中国人不骗中国人,TikTok上建盏开窑直播间忽悠老外,评论笑死

猫小狸同学
2024-06-16 17:42:44
帅到爆炸!50岁吴彦祖胡子一刮,颜值归位,果然是公认的初代男神

帅到爆炸!50岁吴彦祖胡子一刮,颜值归位,果然是公认的初代男神

娱乐白名单
2024-06-17 11:44:27
美国邻居出书,曝刘亦菲及母亲,在美国二婚的生活细节!

美国邻居出书,曝刘亦菲及母亲,在美国二婚的生活细节!

蜉蝣说
2024-06-16 23:59:07
2024-06-17 14:42:44
IT架构师联盟
IT架构师联盟
IT架构实战分享
688文章数 7654关注度
往期回顾 全部

科技要闻

为什么你的iPhone,肯定用不上"苹果AI"?

头条要闻

媒体:和平峰会或让泽连斯基落寞 美带头早退德日跟上

头条要闻

媒体:和平峰会或让泽连斯基落寞 美带头早退德日跟上

体育要闻

豪华阵容,原始战术 英格兰10亿天团就这?

娱乐要闻

上影节红毯:倪妮好松弛,娜扎吸睛

财经要闻

省市级税务人士:目前没有全国性查税

汽车要闻

传奇新篇章 全新一代大众迈腾来了

态度原创

本地
旅游
游戏
房产
公开课

本地新闻

能动司法尽“执”履责 ——“交叉执行”高效能

旅游要闻

游客放狗进赛里木湖追天鹅,景区回应!

《影之诗》续作宣布延期:明年春季推出

房产要闻

强!全国第三!海口房价正在止跌!

公开课

近视只是视力差?小心并发症

无障碍浏览 进入关怀版