1)自我介绍
2)项目介绍
3)为什么要生成静态页?介绍一下静态页生成的流程
那我们就先说一下不生成静态页的情况,不生成静态页那么用户点击详情页就会直接访问数据库来获取数据进行填充模版 , 当大量数据请求过来 , 会导致数据库压力激增,容易使数据库宕机。所以我们采取使用静态页这种方式。因为静态页不仅可以提高网页的性能和效率,还可以减轻服务器负载,并让用户体验更好。
首先我们需要确定网站的内容结构,包括页面、文章、图片和其他媒体等,静态化的方式我们采用的是freemarker模板引擎+minio,我们首先通过freemarker的模板和要改变的数据来生成静态化页面,然后把静态页面存储到minio中。这样用户访问的时候直接去minio中获取就行了,不用查询数据库。从而提升性能,提高用户体验。
其实关于这个问题我们想过用redis缓存,然后查询,但是redis缓存技术适合于小规模的数据,以及动态化的数据。freemarker静态化技术适用于大规模但是变化不太频繁的数据。
4)为什么使用ElasticSearch做文章搜索?
ES是一个分布式的搜索、分析引擎,它更适合海量数据的搜素,因为ES采用的是一个倒排索引,在存储数据的时候,它会对字段进行分词处理,记录每个词语的文档ID,然后把词语和文档ID记录到倒排索引中,当用户执行搜索的时候,会对搜索的字段进行分词处理,在去倒排索引中查询对应的词语,获取每个词语的文档ID,最后根据文档ID去获取文档数据就可以完成搜索了。就比如说我们有1亿的文章,他实际只能分出几十万的词语,从1亿到几十万,这个查询效率会快很多倍,这也是我们采用ES的原因,就是为以后海量数据的查询做考虑。
5)千人千面是如何实现的?
我们会根据用户最近查看的文章或搜索的文章,获取其文章标签和内容,将文章内容使用es进行分词,再将分词后的内容使用DFA算法进行一个过滤,获取其中最热的十个词,用文章标签和文章热词,还有文章阅读时间构建用户模型储存到mongodb中,当用户点击推荐频道时,我们会查询mongodb获取到当前用户模型,获取里面存储用户最近一周查看的文章标签和热词,再根据文章标签和热词查询到相应的文章推荐给用户。
6)如何实现中文+拼音混合搜索?
混合搜索的实现我们需要将ElasticSearch支持的ik和pinyin分词器配置到es中,创建索引库时对指定的字段进行设置分词器即可,默认拼音分词器他会将汉字单独分为拼音,不符合我们的需求,我们可以对其定制,形成自定义分词器,通过自定义分词器将文本按照规则进行切割然后再使用拼音分词器处理即可。
7)风控系统如何设计的?
风控系统专门负责审核图片、文本、视频。风控微服务会监听自媒体微服务发来的消息。在监听到消息后,会查看审核类型,如果是文本审核,则会调用DFA算法来进行本地审核,如果未通过则直接结束将结果返回给自媒体,如果审核通过就会调用aliyun的文本审核api对文本实现一个检查,如果审核失败会将检查到的词存入我们的敏感词库,丰富我们的敏感词库并将结果返回给自媒体,如果审核成功,将审核完的结果再发送到Kafka指定的主题中。如果是视频和图片,直接调用aliyun相关的api,如果审核失败则将结果返回给自媒体微服务,如果审核成功,将审核完的结果再发送到Kafka指定的主题中。
8)介绍支付系统实现
支付组件的实现是基于easy-trade-cloud支付平台实现的,在用户点击下单后,会根据下单信息构建一个交易vo对象,在获取支付渠道信息,我们将渠道配置信息存储在数据库中,为了提高在大量请求下加载速度问题,会将数据库中的信息储存在redis中,根据构建的vo对象中企业信息去redis中获取对应的渠道配置信息,根据获取到的渠道配置信息去调用相应的渠道,进行支付,并生成交易信息存入数据库。
9)用户如果支付了,但你们自己服务器异常了,没收到支付结果,怎么办
我们在支付系统中,可以设置一个自动对账机制,定期与支付服务商进行对账,比对支付服务商记录的支付结果和我们自己系统中的支付记录。如果发现差异,可以通过补偿机制或人工介入来进行调整和解决。
10)支付涉及哪些加密算法?介绍一下RSA、AES算法
支付涉及的加密算法有很多种,其中 RSA 和 AES 算法是比较常见的两种。
RSA 算法是一种非对称加密算法,它利用两个密钥,即公钥和私钥,来进行加密和解密。在支付领域,RSA 算法通常用于数字签名和密钥交换。数字签名可以保证支付信息的完整性和真实性,而密钥交换可以确保支付信息的机密性。RSA 算法的安全性和强度主要取决于密钥的长度,一般来说,密钥长度越长,安全性和强度越高。
AES 算法是一种对称加密算法,它使用相同的密钥来进行加密和解密。在支付领域,AES 算法通常用于对支付信息进行加密保护。AES 算法的安全性和强度主要取决于密钥的长度和加密模式。AES 算法支持多种加密模式,例如 ECB、CBC、CFB 和 OFB 等,每种加密模式具有不同的安全性和强度。一般来说,使用更长的密钥和更安全的加密模式可以提高 AES 算法的安全性和强度。
11)如何制定创收规则?(打赏、浏览量、点击量、评论量、收藏量...Drools规则引擎)
我们可以使用Drools规则引擎指定和文章相关的规则 , 主要遵循的是浏览量、点击量越高,平台给此用户的分佣就越高。当平台在进行分佣的时候,根据我们定义好的规则DRL文件,里面包含了每个分段对应多少佣金的规则条件 , 程序得到此文章的浏览量或者点击量数据,就可以知道这篇文章能够得到多少分佣 , 这个过程是可以递增的,随着量级越高,分佣就越多。
12)文章数量太大,如何存储?(水平分表分库,ShardingSphere-JDBC/ShardingSphere-Proxy,陈旧历史数据归档,存储到MongoDB)
对于文章数量大的问题我们使用ShardingSphere-JDBC实现对文章数据进行水平分表分库,ShardingSphere-JDBC是一个透明的Java中间件,用于分库分表操作。它作为应用程序的依赖库,嵌入在应用程序中,通过JDBC驱动层面进行数据库操作的拦截和路由。应用程序无需改变任何代码,可以通过配置文件定义分片规则、数据源信息和路由策略,实现对数据库的分库分表功能。
使用xxl-job定期对文章数据库进行检查,对比文章发布时间和当前时间进行一个判断,寻找出所有时间间隔大于3年的文章将文章数据存储在mongoDB中,在存入后会进行数据完整性和一致性进行判断,将原始数据删除,只能访问mongodb中的数据。
13)热门文章如何实现?(ZSet、热门数据实时计算)
分析:
热门文章的话 , 我们是使用的redis的Zset实现的 , 因为Zset的数据结构, 它可以将每个元素与一个分数相关联,然后根据分数进行排序。这一特性是比较符合我们的业务需求。
具体实现:
我们可以文章发布的时候同时获得一个基础分数(这分数是根据时间分钟值设置的),当我们发表后,可以通过一些行为对文章进行加分(比如点赞,评论,浏览,收藏,转发等行为),可以对这些行为进行一个设定每个行为的加分值,然后把这些文章存到MongoDB中,之后对redis中数据进行判断比如Redis只存1000条数据,这时候我们就会判断是否有1000条数,如果数据没有1000条数据我们就会直接把数据存储进去,如果数据有1000条数据那就通过RedisZSet对排名最后一位进行热点分数比较,如果新增文章的热点分数大于最后一位的时候就把替换掉,如果小于最后一位数据那就直接返回。
14)如何防止别人频繁发表相同评论(id=每分钟不能发相同评论-时间+IP[分钟]+内容->MD5)
这里的话,我们使用的是MD5校验的方式 , 将这个用户id+用户发布的评论内容+用户ip+分钟时间戳作为key , 然后将这个key进行MD5加密处理(防止重复) , 评论内容作为value,存入到评论数据库( mongoDB ) .。
当此用户在同一分钟内再次发布评论的时候 , 会先根据 用户id+用户发布的评论内容+用户ip+分钟时间戳组成的key去评论数据库进行查询,判断数据库时候有这个key, 就判断内容是否相同. 如果key和value都相同就抛出异常(短时间不能发布相同评论,请稍后重试!)这样就解决了频繁发布相同评论的问题。
15)视频用什么存储(MinIO)?视频如何做分片?(ts,m3u8)
我先给您讲一下minio的好处:
1.高可靠性:MinIO 是一款分布式对象存储系统,支持数据冗余和多副本备份,可以保证数据的高可靠性和可用性。
2.高扩展性:MinIO 可以通过水平扩展的方式,实现存储容量的无限扩展,可以满足不同规模和需求的存储需求。
3.高性能:MinIO 基于 S3 协议,采用高性能的分布式存储架构,可以实现高并发、高吞吐量的数据访问和传输。
4.成本低廉:MinIO 是开源的对象存储系统,使用成本较低,可以节约企业的存储成本。
5.安全性高:MinIO 支持数据加密、访问控制等功能,可以保障数据的安全性和隐私性。
6.多种数据访问方式:MinIO 支持 S3、NFS、SMB 等多种数据访问方式,可以方便地与其他系统进行集成和交互。
问题一: 根据minio的优点,使用的是Minio存储视频的方式 .
问题二:
在我们的项目中是使用的FFmpeg库进行视频分片的,因为FFmpeg 库可以对视频编解码和分片处理。
以下是使用 Java 调用 FFmpeg 库实现视频分片的基本步骤:
1.首先需要在服务器上安装 FFmpeg 库,以便在 Java 代码中调用 FFmpeg 库进行视频编解码和分片处理。
2.在 Java 代码中,可以通过 ProcessBuilder 类来创建一个子进程,然后调用 FFmpeg 命令来进行视频分片处理。
3.上传 TS 文件和 M3U8 文件:将生成的 TS 文件和 M3U8 文件上传到服务器中,以便客户端进行下载和播放。
在客户端中播放视频:在客户端中,通过 HTTP 协议下载 M3U8 文件和 TS 文件,然后按照顺序播放其中的视频内容。
16)文章如何数据批量导入ES?(xxl-job、分页批量导入)
海量数据批量导入ElasticSearch这块 , 当我们有1000万数据的时候 , 要将这个数据导入到ES或者MYSQL的时候可能会有这样几个问题:
1. 数据量太大,导入数据超时的问题或者可能会使数据库直接宕机
2. 将所有数据加载到内存可能会导致内存不足 , 严重影响系统性能,或者甚至导入失败
3. Elasticsearch默认配置了每秒最大并发请求数量,如果导入过程中并发请求数量过多,可能会导致请求被拒绝。
解决方案:
对数据进行分批处理 , 避免一次性加载所有数据,所以我们可以启动多个服务,用xxl-job分片模式分页批量导入数据到ES,可以大幅提升系统效率,并且不会导入数据库宕机和超时的问题。
实现流程:
首先我们可以查出所有文章的总数 , 将文章总数计数为count , count就是需要生成静态页的总条数 , (根据xxl-job的特性)然后查出分片节点总数total 和 当前节点参与该任务节点总数中的下标index , 根据分片总节点数和数据总条数可以计算出每个分片最大处理的数据量size , 并计算出开始范围和结束范围page。处理数据的开始范围就是(节点下标-1)×每个分片处理的最大条数 , 结束范围就是 (节点下标×每个分片处理的最大条数-1) ,++++这样就可以知道每个分片服务需要执行的大分页的区间 , 根据page和size每个分片都执行对应的分页查询 ,拿到所有分页数据,并将静态页url更新到数据库, 将数据构建成IndexRequest对象,使用BulkRequest实现批量导入,在使用RestHighLevelClient对象将数据上传至ElasticSearch。
17)文章如何定时发布?(基于Cookie实现xxl-job登录,实现任务远程管理)
我们先说一下远程调用xxljob:
首先可以先查看执行xxl-job的操作需要哪些参数和请求地址 ,因为xxl-job的用户登录在我们数据库有 ,可以根据用户名和密码生成token,。
第一种方式:不需要修改源码 , 直接将令牌封装到cookie里面,然后使用Resttemplate的exchange方法封装参数并发起请求 , 就可以远程调用xxl-job。
第二种方式,需要修改源码,在登陆校验添加 判断cookie中是否没有token,如果没有就查询请求头中的token,然后我们可以把token添加到请求头中再发起远程请求,实现远程调用。
具体实现:
首先我们需要判断自媒体用户发布的文章的发布时间是即刻还是未来时间(大于系统当前时间即为未来世界), 判断是未来时间还是当前时间, 根据未来时间创建CRON表达式 , 封装参数, 请求xxljob的添加任务接口 , 并开启任务。
18)你们系统中的数据都是你们用户发布的吗?爬虫爬数据后,如何处理?
不是,单单仅用户发布的话 , 一开始的数据量肯定比较少 , 我们这边使用的是爬虫技术.
使用java代码实现Jsoup库爬取新浪新闻:
这里可以使用Jsoup 库爬取新浪新闻 , 可以将爬取的新浪新闻的数据存入到mysql数据库 , 然后我们查询数据并调用文章微服务的自动审核功能 , 实现审核并添加数据到用户APP端,并且使用xxl-job批量生成静态页,这样在自媒体段和用户APP端都可以浏览。
19)在线私聊如何实现?(Websocket+Netty)
我们通过Websocket+Netty来实现实时通讯,可以建立用户和作者实时的双向通信。普通用户可以在小程序端或网页端发起咨询请求,作者端通过Netty的事件处理机制来接收和处理普通用户发送的咨询请求接收并回复咨询信息。咨询过程中,可以实时传递消息、文件等,并保持长连接。普通用户发送咨询请求后,服务端接收到请求并建立Websocket连接。作者端监听新的咨询请求,接受并处理请求。在双方建立连接后,可以通过Websocket进行实时的消息交互,包括文字、图片、文件等。
在线实时直接推送新消息实现:用RabbitMQ将消息数据推送给Netty,Netty从连接池中取出接收者的WebSocket连接,Netty通过接收者的WebSocket连接返回新消息的数量。
如果作者或者用户不在线登录之后查询消息列表:接收者向服务端Netty请求和WebSocket连接,Netty服务把连接放到自己的连接池中去,根据接收者信息向RabbitMQ查询消息,如果有新的消息,直接返回新消息通知,使用WebSocket连接,接收者就会返回新消息的数量,以此来实现查看。
20)广告系统是如何实现的?(竞价排名)
广告系统我们可以新开一个端 , 专门负责广告系统的CRUD .
首先,在Elasticsearch中创建一个索引来存储你的搜索数据,将数据导入到对应的索引库,使用functionScore算法函数过滤出我们需要进行加分的广告,根据他给的广告费用进行一个合理的加分操作,在用户查询相关的信息时,平台会根据竞价排名算法计算广告的展示顺序,将竞价较高的广告出现在更显眼的位置。