基于SpringCloud的广告系统设计与实现(四)

一、基于SpringCloud的广告系统所使用的技术

技术名称 作用功能 主要用途 核心组件 依赖技术 备注
Zuul API网关功能,提供请求路由、过滤、负载均衡等。 作为微服务架构的统一入口,提供安全、监控、路由等功能。 Zuul Server、Zuul Filter Spring Boot、Netflix Zuul 被Spring Cloud Gateway逐渐替代。
Eureka 服务注册与发现功能。 用于微服务的注册与发现,支持高可用的服务注册中心。 Eureka Server、Eureka Client Spring Boot、Netflix Eureka 被Spring Cloud Alibaba Nacos替代的趋势。
Hystrix 断路器功能,用于容错和防止级联故障。 保护微服务架构中的关键依赖项,避免因单点故障导致整个系统崩溃。 Hystrix Command、Hystrix Dashboard Spring Boot、Netflix Hystrix 被Resilience4j等替代的趋势。
Actuator 提供应用监控和管理功能。 用于监控微服务的健康状态、指标、审计等,支持多种端点(如健康检查、度量、日志等)。 Actuator Endpoints Spring Boot 广泛用于微服务的监控和管理。
OpenFeign 声明式服务调用客户端,简化微服务间的远程调用。 提供基于接口声明的远程调用功能,支持负载均衡和断路器。 Feign Client Spring Boot、Ribbon、Hystrix 基于Feign实现,简化微服务调用。
Ribbon 客户端负载均衡功能。 用于微服务间的负载均衡,支持多种负载均衡策略。 Ribbon Client Spring Boot、Netflix Ribbon 常与Eureka、OpenFeign配合使用。
Processor 处理器功能,用于数据处理和转换。 用于数据流处理、批处理任务等,支持任务的编排和执行。 Data Flow Server、Task Client Spring Boot、Spring Cloud Stream 包括Spring Cloud Data Flow、Spring Cloud Task等。

二、SpringbootCloud服务调用

微服务之间的调用

注册到 Eureka Server 的各个微服务之间可以通过SpringCloud自带的组件实现服务之间的调用
Ribbon 方式调用

  • Ribbon是一个客户端负载均衡器,可以很好的控制HTTP 和 TCP 客户端的行为
  • SearchApplication.java 中完成注入,并标记@LoadBalanced 开启负载均衡的功能
  • SearchController.java 中通过 RestTemplate 调用服务接口,与常见的RestTemplate不同的是,调用使用的不再是 ip+ port,而是服务名。这是通过注册中心(Eureka Server)实现的。Feign 方式调用

Feign可以实现声明式的 Web服务客户端

  • 通过@FeignClient 指定调用的服务名称
  • 在接上声明@RequestMapping指明调用服务的地址与请求类型
  • 通过在@FeignClient 中配置fallback 指定熔断
  • 实现接口:SponsorClient.java,熔断:SponsorClientHystrix.java

1.Ribbon/Feign的关系

在Spring Cloud中,Ribbon和Feign都是用于实现客户端负载均衡的工具,但它们在使用方式和功能上有明显的区别。以下是Ribbon和Feign的关系、区别以及它们在微服务架构中的作用:

Ribbon和Feign的关系

特性 Ribbon Feign
核心功能 客户端负载均衡 声明式服务调用(基于接口)
是否支持负载均衡 支持(核心功能) 支持(通过集成Ribbon实现)
是否支持断路器 不直接支持(需结合Hystrix) 支持(默认集成Hystrix)
使用方式 基于HTTP客户端(如RestTemplate) 基于接口声明(代码更简洁)
依赖关系 独立于Feign 内部依赖Ribbon实现负载均衡
是否需要配置 需要配置(如服务列表、负载均衡策略) 配置更简洁(基于接口注解)

详细说明

1. Ribbon
  • 功能:Ribbon是一个基于HTTP和TCP客户端的负载均衡器,用于在客户端实现负载均衡。

  • 工作方式

    • Ribbon通过与服务发现组件(如Eureka)集成,动态获取服务实例列表。

    • 客户端在调用服务时,Ribbon会根据配置的负载均衡策略(如轮询、随机等)选择一个服务实例进行调用。

  • 使用场景

    • 通常与RestTemplate结合使用,通过@LoadBalanced注解启用Ribbon的负载均衡功能。

    • 示例:

      @Bean
      @LoadBalanced
      public RestTemplate restTemplate() {
          return new RestTemplate();
      }
      
2. Feign
  • 功能:Feign是一个声明式的服务调用客户端,通过接口声明的方式简化微服务间的调用。

  • 工作方式

    • Feign内部集成了Ribbon,用于实现客户端负载均衡。

    • Feign通过定义接口和注解(如@FeignClient)来声明服务调用,底层通过Ribbon选择服务实例。

    • Feign还支持断路器(Hystrix),默认集成了Hystrix功能。

  • 使用场景

    • 通过定义接口和注解,Feign可以简化服务调用的代码,使代码更清晰、更易维护。

    • 示例:

      @FeignClient(name = "service-name")
      public interface ServiceClient {
          @GetMapping("/api/endpoint")
          String getSomething();
      }
      

Ribbon和Feign的集成关系

  • Feign依赖Ribbon

    • Feign内部集成了Ribbon,用于实现负载均衡功能。

    • 当Feign客户端调用服务时,Ribbon负责选择具体的服务实例。

  • Feign简化了Ribbon的使用

    • Feign通过接口声明的方式隐藏了Ribbon的复杂性,使开发者更容易实现服务调用。

    • Feign的配置更简洁,通常只需要定义接口和注解即可。


总结

  • Ribbon :是一个独立的客户端负载均衡器,通常与RestTemplate结合使用。

  • Feign:是一个声明式的服务调用客户端,内部集成了Ribbon,用于实现负载均衡。

  • 关系:Feign依赖Ribbon实现负载均衡功能,但Feign通过接口声明的方式简化了Ribbon的使用。

  • 实际开发使用的是 Feign

2.@IgnoreResponseBody

@IgnoreResponseBody 的使用场景是当你不需要这个 Controller 方法返回统一响应格式的时候才会使用的。

3.springcloud 内部服务之间的调用

网关的目的是作为给外界(客户端、前端)暴露的接口,内部调用没有必要走网关。

4.实际开发中,Feign的开发模式

  1. 不同的开发人员提供的微服务(通过 Feign 调用的场景),通常是应该包含文档的,而且提供给其他服务调用的应该是一个 SDK。这个 SDK 里面只包含两类内容:第一类是请求和响应对象(这样调用方和被调用方都可以引入直接用);第二类是封装好的 FeignClient(正如你所说的,实际上就是这样用的);

  2. 在开发一个微服务的时候,一般会有三个包,分别是:

XXX-microservice(对外提供接口,即只定义 Controller),XXX-service (service 层,即服务功能实现层),XXX-sdk (请求对象和响应对象定义,FeignClient 定义)

  1. 如果多个微服务模块都会用到同一份代码定义,那么,是可以抽象出来放到 common 中的,这是非常合理的,也是经常采用的方式。

5.使用 Feign的时候,要重复定义请求与响应对象,你会怎样修改,让它们只定义一次呢?

ad-common 这样的通用模块定义 "特定的" 代码并不合适,因为这些代码只是在特定的微服务调用时才会用到,而不是所有的代码都需要用到。

更合适的做法是再定义一个叫做 sdk 的项目,这里面只定义微服务调用用到的请求对象和响应对象,而不涉及具体的实现类。

6.使用Feign的时候抛出了异常,你觉得需要做兜底的回退吗?为什么?

关于兜底回退是需要考虑实现成本的。OpenFeign 的方式调用微服务,并设置了 Hystrix 熔断,这时,Hystrix 会把调用过程包装在自己的线程池中,且会在内存中记录调用信息(所以,才能够通过 Hystrix Dashboard 看到调用信息)。所以,这比直接调用要慢很多。通常,我们不会定义兜底回退,因为当你的程序已经抛出异常了,你能做的事情很有限,不如直接检测到异常,修复问题更加直接、合理。

服务之间的调用栈不能太深,且微服务之间不应该做多处保存。


学了很久,服务启动正常,我基本都未操作了,也没有调用一下接口,所以访问下接口:

http://localhost:9000/imooc/ad-sponsor/get/plan

访问后就发现报错,com.netflix.zuul.exception.ZuulException: Forwarding error

处理方式:

SpringCloud Zuul启动访问接口报错 com.netflix.zuul.exception.ZuulException:xxx的解决办法_spring-cloud-netflix-zuul-websocket启动报错-CSDN博客

注意:加在ad-sponsor的配置中。


三、广告数据索引设计

1.正向索引

2.倒排索引

倒序索引,存储在内存中,检索速度很快,检索效率是几十 ms ~ 100 ms 级别的。 ES 的检索效率是秒级别的,当然,速度快的话是几百个 ms 级别的。

3.全量索引+增量索引

要过年了,收尾了。

祝大家新年快乐,过年一起读书。最近发现人体简史,让我对各类简史的书充满极大的兴趣,比如万物简史,时间简史,人类简史,万物简史,规律简史等等。我来探探这些书,弥补年少未读这些优秀之作的遗憾。目前不卷更好的自己了,只愿自己怡然自得吧。

相关推荐
gentle_ice5 分钟前
leetcode——搜索二维矩阵II(java)
java·算法·leetcode·矩阵
程序员徐师兄12 分钟前
Java实战项目-基于 springboot 的校园选课小程序(附源码,部署,文档)
java·spring boot·小程序·校园选课·校园选课小程序·选课小程序
TANGLONG2221 小时前
【C++】类与对象初级应用篇:打造自定义日期类与日期计算器(2w5k字长文附源码)
java·c语言·开发语言·c++·python·面试·跳槽
等一场春雨1 小时前
Java设计模式 二十六 工厂模式 + 单例模式
java·单例模式·设计模式
mqiqe2 小时前
Spring AI DocumentTransformer
人工智能·spring·原型模式
纪元A梦2 小时前
Java设计模式:结构型模式→桥接模式
java·设计模式·桥接模式
&白帝&3 小时前
JAVA JDK7时间相关类
java·开发语言·python
2301_818732063 小时前
用layui表单,前端页面的样式正常显示,但是表格内无数据显示(数据库连接和获取数据无问题)——已经解决
java·前端·javascript·前端框架·layui·intellij idea
狄加山6753 小时前
系统编程(线程互斥)
java·开发语言
星迹日3 小时前
数据结构:二叉树—面试题(二)
java·数据结构·笔记·二叉树·面试题