ProjectLearning2
广告投放系统
类
CommonResponseAdvice
将字段进行包装进行填充,规范化API返回格式:通过统一响应,可以定义API的返回格式,包括状态码、消息、数据等内容,使得不同的接口返回风格一致,提高了接口的可预测性和可读性。
JpaRepository的继承过程
Feign和Hystrix
关于Feign和Hystrix的整合,可以参考以下文章:
如何理解服务调用,阶段器和负载均衡
RESTful
有关RESTful的介绍,可以参考以下文章:
浅谈restful
注解
- @Transactional,声明一个方法需要进行事务管理,并指定事务的隔离级别、传播行为和超时时间等属性。
思想
- 接口可以继承自什么?
接口可以继承自接口,但不能继承自类。这意味着一个接口可以通过使用关键字 extends 来扩展(继承)另一个接口。通过接口继承,子接口可以获得父接口中声明的方法签名,但不包括方法的实现。
binlog
binlog原理
- 主库将数据库中的数据的变化写入到binlog日志文件中
2 从库通过连接主库 - 从库会创建一个i/o线程,用于读取主库的binlog日志文件,并将数据的变化同步到自己的数据库中。
- 主库会创建一个binlog dump线程,用于将binlog日志文件发送给从库的i/o线程。
- 从库的i/o线程接收到binlog日志文件后,会写到relaylog日志文件中。
- 从库的SQL线程会读取relaylog日志文件中的数据变化,并将其应用到自己的数据库中。
如何避免主从延迟
如果我们无法忍受主从同步延迟我们可以又两种方法进行解决
- 强制将读请求路由到主库处理
- 延迟读取
如果主从同步延迟是0.5s,我们就1s后进行读取数据
什么情况下会出现主从延迟,如何尽量减少延迟
其中又两个io我们可以想到,明显是由于两个io的速度不一致导致的
- 其中第一个io是从库接受binlog的速度明显跟不上主库写入binlog的时间
- 第二个是从库的sql线程执行relaylog的速度明显跟不上从库接受binlog的速度
我们可以考虑从优化上述的机器性能进行解决问题
分库分表
什么是分库
分库就是将数据库中的数据分散到不同的数据库中,可以垂直分库,也可以水平分库
垂直分库就是将不同的表分散到不同的数据库中,水平分库就是将不同的数据分散到不同的表中
举个例子
- 垂直分库
将不同的业务逻辑进行分库 - 水平分库
将表的主键按照一定的原则进行划分
什么是分表
分表就是将一张表中的数据分散到不同的表中,可以垂直分表,也可以水平分表
垂直分表就是将不同的字段分散到不同的表中,水平分表就是将不同的数据分散到不同的表中
举个例子
- 垂直分表
就是根据表的属性进行划分 - 水平分表
就是将按照主键的id进行划分
消息队列
消息队列有什么用
一共有三个作用
- 解耦
- 异步处理
- 削峰填谷
其中我的项目用到了两种作用 - 其中的第一个作用是进行解耦,binlog的其中一个缺陷是多服务器时会造成数据库压力大
而我们知道消息队列使用的时发布-订阅模式进行工作,这时我们新增从数据库我们可以进行直接订阅,从而实现网站业务的可扩展性设计 - 其中的第二个作用是进行异步处理,在广告投放系统中,我们使用消息队列进行广告投放的异步处理,从而实现广告投放的效率
讲一下什么时JMS和AMQP
- JMS(Java Message Service)
JMS是Java平台中关于面向消息中间件的API,它定义了用于创建、发送、接收消息的Java应用程序接口,用于在JVM的两种或多个应用程序之间,进行异步通信。 - AMQP(Advanced Message Queuing Protocol)
AMQP是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。
RPC和消息队列的区别
- 从用途上来看
RPC是远程过程调用,用于服务之间的调用,而消息队列是用于服务与服务之间的通信,两者都是用于服务之间的通信 - 从通信方式上来看
RPC时双向直接网络通讯,而消息队列时单向引入中间载体的网络通讯 - 从架构上来看
消息队列时将消息存储起来,RPC则没有这个要求,RPC时双向直接网络童鞋你 - 从请求处理的时效性来看
RPC是同步请求,而消息队列是异步请求
kafka常见问题
kafka是什么
kafka是一个分布式的消息队列,它具有高吞吐量、低延迟、高容错性等特点,可以用于处理大量的数据,并保证数据的可靠性。
队列模型和kafka的消息模型
- 队列模型
队列模型是一种常见的消息传递模型,它将消息存储在一个队列中,并使用消费者来消费这些消息。队列模型通常用于异步处理和广播消息。 - kafka的消息模型
kafka的才写出模型使用发布订阅模型去解决这个问题,就比如我们使用主题作为消息通信载体,类似广播模式,发布者发布一条消息,改消息通过
主题传递给所有的订阅者,在一条消息广播之才订阅的用户时收不到该条消息的,如果只有一个订阅者,那么他的模型和队列模型时基本一样的
kafkfa核心概念
- producer
生产者是消息的发布者,它可以将消息发送到kafka的topic中 - consumer
消费者是消息的订阅者,它可以从kafka的topic中消费消息 - broker
broker是kafka的服务器,它负责存储消息和处理消费者的请求
同时我们可以注意到,topic和partition - topic: producer将消息发送到特定的的主题,consumer可以从特定的主题中消费消息
- partition: 属于topic的一部分,一个topic可以有多个partition,通俗的可以理解为一个消息队列中的队列
zookeeper在kafka中的作用
- broker注册
在zookeeper上会有一个专门用来进行broker进行broker服务器列表的节点,每个broker在启动时都会向该节点进行注册,从而将broker服务器列表进行更新 - topic注册
在zookeeper上会有一个专门用来进行topic进行topic服务器列表的节点,每个topic在启动时都会向该节点进行注册,从而将topic服务器列表进行更新 - 负载均衡
当producer向kafka发送消息时,会根据topic找到对应的partition,并将消息发送到该partition所在的broker服务器上,从而实现负载均衡
kafkfa如何保证消息顺序,消息丢失和重复消费
- 消息顺序
kafka只能保证在partition中的消息顺序,不能保证在topic中的消息顺序
每次进行添加到partition时,都会才用尾加发,kafka只能保证在partition中的消息顺序,不能保证在topic中的消息顺序 - 消息丢失
kafka有三种常见丢失消息的情况- 生产者丢失消息
生产者丢失消息的原因可能是网络问题,或者producer在发送消息时发生了异常,从而导致消息丢失 - 消费者丢失消息的情况
在生产者给消费者消息的时候会给一个offset用来确认是否接受到消息,如果提交了offset后但是并没有接受到消息那么就会发生这种情况 - kafka丢失消息
kafka丢失消息的原因可能是kafka服务器发生了异常,或者kafka服务器发生了重启,从而导致消息丢失
- 生产者丢失消息
kafka如何保证消息不重复消费
根本原因是消费者已经消费,但是没有提交offset
kafka侧由于服务端处理业务时间过长而导致了kafka认为服务假死
从而导致消费者重复消费
消费失败会怎样
在默认情况下,当消费异常会进行重试,重试多次后会跳过当前消息,继续进行后序消息的消费
默认情况下会进行消费10次数
业务思想
好难啊啊啊啊
- 1. 首先使用构建增量索引作为广告检索服务
- 2. 使用mysql中的Master-Slave协议,通过slave监听binlog日志实现日志,达到数据一致性的目的
- 3. Kafka投递解析后的binlog日志,方便后续统计业务等,并维持索引(增量索引)。
- 4. 检索广告的索引,实现条件匹配,并返回响应.
思考
- SpringCloud 和 Dubbo的选择问题,zuul和Gateway的选择问题
SpringCloud和Dubbo从原理上和思想几乎一样,由于Springcloud由于更加完善的微服务 - Eureke中维护了Client中的哪些信息? 又怎样存储这些信息
在其中注册了一个Instanceinfo实例,该实例中存储了Client的相关信息,如实例的id实例的ip地址,实例的端口号等 - 对数据表分层级的原因
使用了逻辑分层
- 标识表与表之间的依赖关系,比如Level3依赖于Level2,值,可以避免了出现空指针的代码,使用了依赖关系可以进行逐层检查
- 表的逻辑分层可以简化了处理相同的业务逻辑的代码,比如Level2和Level3的表中都有相同的字段,那么我们可以将相同的字段进行提取,然后使用一个公共的类进行存储,从而简化代码
- 为什么要把全量数据导出到文件中,而不是直接从数据库中加载
首先导出到文件需要放在公共的文件系统中
服务是多实例存在,同时操作数据库会造成巨大的压力 - 为什么广告数据要放在JVM内存中,如果太多放不下怎么办
我们将数据放在了concurrentHashMap中,这样就放在了JVM内存中,考虑到了快的原因
对于第二个问题,使用数据hash分区的策略,我们可以进行将数据时分散到不同的分区里面,每台机器只维护少量的源信息
其次owomf可以使用redis缓存系统, 由于广告数据的数据不大,我们不考虑 - Binlog是什么?如果监听的过程中,MySQL宕机了,再次启动服务,会是什么情况?
Mysqlserver有四种类型的服务日志,error log,general query log,slow log,binlog
其中binlog是用来记录数据库的变更的日志,可以用于数据恢复,数据同步等
监听binlog有两种做法:
- 不添加任何配置,自动监听最新的日志
- 指定想要读取的binlog pos,记录指定位置的pos
在每一次进行读取的时候我们只需要进行实时的记录每一次的postition就可以
- 为什么选取Binlog作为增量数据的收集方案
其实是可行的,我们可以通过Ribbon,feign等框架进行负载均衡,从而实现数据的同步
问题是代码冗余,实现起来我们需要在实现的时候进行写一份代码,然后将数据进行同步过去,有可能导致数据不稳定
检索系统需要知道数据表的定义,广告检索系统应该是不知道数据表的定义的
投放系统与检索系统之间存在严重的耦合 - 为什么要把BinLog的增量数据发送到Kafka上,微服务再去订阅kafka的信息
如果不使用kafka,那么我们就会导致一个问题那就是会导致所有的服务实例进行监听Mysql服务器,会导致数据库的压力
检索系统可以进行订阅kafka进行订阅
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment
WalineFacebook Comments