旅游项目

简介: 本项目涵盖酒店预订、支付系统、短信平台、风控审核、权限管理、推荐系统等多个模块。采用微服务架构,结合Redis、RabbitMQ、ES、MongoDB等技术,实现高并发场景下的稳定服务。支持短信防刷、订单超时取消、优惠券发放、分布式锁控制、Drools规则引擎、拼音搜索、数据分片、权限控制、红包抢夺算法及个性化推荐等功能,保障系统安全性与用户体验。

1)自我介绍

2)项目介绍

3)短信平台有哪些功能?

短信平台这块有短信发送的功能,用户可以在平台提供的界面填写短信内容和接收者的手机号,然后发送短信。还有短信模板功能,用户可以事先在短信模板这里添加自定义短信模板和修改模板,以方便用户在发送短信时使用。还有群发功能,用户在发送短信时可以选择给多个接收者发送短信,这个功能对批量通知和市场推广等需求非常有用。还有定时发送功能,用户可以提前定时发送短信,这功能非常适合节日祝福和提醒等场景。还有短信统计和分析功能,可以把发送量、成功率、响应率等数据的报表和图表进行分析,帮助用户了解短信发送的效果和趋势。

4)短信平台如何防刷?

我们可以使用验证码的形式来做到防刷,比如说用户需要输入正确的验证码才能发送短信。也可以使用手机号限制来实现,比如说可以限制每个手机号发送验证码的次数,到次日凌晨0点重置次数就可以实现防刷。可以使用mongodb存储手机号和对应的次数,在每次执行更新次数操作后进行验证,如果次数达上限就执行拦截或报警逻辑代码。也可以使用限制ip的方式来实现,比如说某一个ip发送短信频率很高,我们就把当前ip暂时给封禁掉,可以使用布隆过滤器实现,首先要初始化布隆过滤器,选择合适的过滤器大小和哈希函数数量,然后添加要限制的ip,使用多个哈希函数对这个ip地址进行哈希运算,并且将对应的位标记为1,当那个IP再次进来时,如果多个哈希函数的计算结果都是1,布隆过滤器就会认为这个ip是要被限制的ip,就是验证不成功,就对这个ip的请求进行拒绝。还可以设置一个审核机制,对用户提交的短信内容进行审核,确保发送的短信内容符合相关法规和规定,只有通过审核的短信才能被发出去。也可以设置一个异常监测和报警系统,如果发现异常发送次数增加和异常流量等情况,设置相对应的报警机制,及时的采取措施解决问题。

(参考)

防止短信防刷有很多方法,一下简单说几种

第一种:用户获取验证码的时候进行一分钟倒计时,确保用户在一分钟内只能请求一次验证码。这也就保证了用户,一分钟只能发送一次短信。但是如果刷新页面后,再次获取验证码,就会重置60秒,所以验证码的60s必须是严格意义上的60s。并且需要给验证码设置超时时间。

我们可以使用Redis将申请验证码的手机号作为key存入到Redis中,并记录获取验证码的时间,如果下次获取验证码的时间距上次不足60秒不能再获取验证码,同时将验证码作为value,设置10分分钟过期时间,确保这个验证码10分钟内有效。注意:(这种方式无法彻底解决短信攻击问题。)

第二种:流程改进:在发送验证码前,进行其他认证操作,比如密码设置、身份识别、输入更多信息等,使得虚假信息无法正常发送。

第三种:ip防护:对发起发送请求的服务器ip进行限制。一般黑客发起攻击的服务器较为有限,当大批量的请求部署在服务器上时,后台会跟踪到频繁发送请求的黑客服务器ip地址,可以对其地址进行类似黑名单的管制。当发现同一个ip短期发送大量请求时,可以限制其访问。注意:(这种方式也无法彻底解决短信攻击问题。)

第四种:图文验证码:在发送验证码前,必须先进行图文识别,通过后才可发送验证码;除了有相当高的图文验证码识别技术,一般图文验证码是不容易被识别的,因此也是最有效的防攻击手段。

5)介绍一下酒店预订的流程

用户在小程序端执行酒店搜索后,可以根据自己的喜好和需求选择适合的酒店及其房型,在用户提交预订信息前,前端会异步请求后台验证所选房型的可用性。我们使用了redisson分布式锁去防止多个用户同时预订到同一个房间的情况发生。用户选定后点击酒店预订,客户端就会携带下单参数向服务器发送下单请求,订单微服务收到请求后,就会生成一个预支付订单返回给客户端,用户的页面会跳转到预订界面。

首次预订时,用户需要在预订页面输入完整的预订人信息,也可以在个人中心设置默认人员信息,这样,当用户跳转到预订页面后,其预订人信息可以自动填充,减少用户的输入工作量。用户点击支付,在支付页面会显示订单概览信息,以便用户确认和核对。同时,用户可以使用优惠券、积分抵扣等,让用户享受更优惠的价格。同时,对于15分钟内未支付的订单,我们利用xxl-job设置了超时自动取消订单的机制。用户输入支付密码时,为了防止支付过程中出现异常(如支付失败、网络问题等),及时向用户提供友好的错误提示,引导用户重新支付或选择其他支付方式。同时,在数据库记录支付失败的原因,方便后续调优。用户输入密码后,会向后台提交支付请求,微信支付平台进行校验。如果授权通过,会跳转到一个提示预订成功的页面,并展示相应的预订信息,如预订人、预订时间、酒店信息等。同时,可以将预订信息保存到数据库中,以便后续参考和查询。最后,短信平台会给用户发送信息告知用户预订成功及重要的预订信息(如预定时间、酒店信息等)。

6)介绍支付系统实现

我们的这个项目中酒店端、平台端、旅游团端都会涉及到支付功能,同时考虑到支付功能会涉及到付款表、交易表和日志记录等多个表项。于是我们在这项目中,把支付功能抽离出来做的成一个支付系统/支付微服务。

在我们的这个支付系统中,引入了公司已经封装好的支付模块,封装了支付相关的配置信息、API工厂以及支付、查询订单、退款等支付相关功能,然后自定义规则策略并创建实现类方法来实现支付的一系列功能,并暴露出功能接口。

关于支付系统中的功能,我们也进行了优化,比如说:使用seata-AT模式来保证服务调用间的事务性、使用redisson分布式锁来解决订单重复提交的问题、多渠道支付路径的适配处理及幂等处理等等。同时,考虑到支付结果的回调,我们会在向支付平台发送订单信息的时候封装回调地址并创建监听器,来接受处理结果,我们还使用xxl-job创建了一个定时器来向支付平台发起轮询来接受处理结果。

7)用户如果支付了,但你们自己服务器异常了,没收到支付结果,怎么办

首先出现这种情况主要是服务器与支付平台之间网络连接出了问题或者数据传输过程中出现了数据丢失导致服务器没有收到处理结果,即处理结果同步失败。在用户支付完成后,基于三方异步通知,我们在向支付平台发送的订单信息中封装回调地址,支付平台会主动根据该地址向服务系统发送处理结果。同时,创建监听器用来接受处理结果的请求后,会使用Map来进行封装,并对其中的处理结果信息进行校验,如果出现异常则会向用户发送短信提醒以及向服务服务端发送报警信息。同时,因为监听器是使用rabbitmq进行消息同步的,所以我们可以对rabbitmq进行优化,比如:消费者的消息确认,我们使用的是auto,当出现异常时返回nack,没有异常,返回ack;消费者失败重试机制,当消费失败时,会不断进行重试,但是RabbitMQ默认当重试机会耗尽时,将会返回ack,并删除消息;于是我们加上失败策略,当重试次数耗尽,返回nack,将消息重新入队。

8)支付涉及哪些加密算法?介绍一下RSA、AES算法

在微信支付中,会使用AES对称加密算法来对敏感信息进行加密,比如用户手机号、订单号等,同时,在我们使用支付微服务时,服务端会使用公钥对订单信息进行加密,公钥使用的就是RSA非对称加密算法。微信支付平台会使用SHA-256算法对数据进行散列计算,例如生成支付凭证和验证响应数据的真实性,以及HMAC-SHA256 签名算法来生成请求和响应数据的签名,用于验证数据的真实性和防止篡改。

在支付宝支付中,公钥的加密和私钥的解密会使用RSA加密算法来保证数据的安全性;也会使用AES算法来对敏感信息进行加密。同时,支付宝支付平台会使用MD5加密算法来验证响应数据的合法性,也会使用HMAC-SHA256 签名算法来生成请求和响应数据的签名。

RSA(Rivest-Shamir-Adleman)算法:

①RSA是一种非对称加密算法,被广泛用于数据加密和数字签名。

②RSA使用两个密钥,一个公钥和一个私钥。公钥可以公开给任何人使用,而私钥只能由密钥的持有者保密。

③公钥用于加密数据,私钥用于解密数据。

④RSA算法基于数学难题,其中一个关键操作是大素数的分解。它的安全性依赖于这个分解问题的困难性,即通过已知公钥无法轻易地计算出私钥。

⑤在支付系统中,RSA常用于数字签名,用于验证数据的完整性和身份认证。

AES(Advanced Encryption Standard)算法:

①AES是一种对称加密算法,也被称为Rijndael加密算法。

②AES使用相同的密钥来加密和解密数据,因此被称为对称加密算法。

③AES算法支持不同的密钥长度,包括128位、192位和256位。

④AES算法的核心是一系列复杂的替代、置换和混淆操作,通过多轮迭代加密来保证数据的安全性。

⑤在支付系统中,AES常用于加密支付数据,如支付信息、交易记录等。

支付系统通常采用多种加密算法的组合来提供更高的安全级别。比如使用RSA进行加密通信以实现对称加密算法AES密钥的安全传输,然后使用AES对具体数据进行加密保护。这种组合使用不同的加密算法结合各自的优势,同时也进一步加强了支付系统的安全性。

9)订单超时取消如何实现的?

我们这边和同事其实写过三种方案,第一个方案就是在订单创建的同时,使用xxljob创建一个定时任务,假定我们的订单超时时间为三十分钟,那么我们创建的定时任务时间就是订单创建时间的基础上加30分钟,当用户订单创建时间超过三十分钟之后,就会触发xxljob的定时任务,通过这个订单的id去数据库查询此订单的状态,如果为未支付状态,则修改订单状态为取消,并备注原因为,用户超时未支付。最后还会创建一个定时扫描的xxl-job定时器,会每10s扫描mongodb中文档信息,扫描到订单状态变化为非待付时(当用户主动取消订单或者支付订单后,会同时修改mongodb中的订单状态),就会通过文档中的jobId删除自动取消的定时任务以及该文档,否则会判断创建时间到现在是否已经过了25分钟,如果是则会向用户发送短信提醒用户。第二个方案就是在订单创建的同时,使用延时消息,这边我们选用的RabbitMQ进行创建延时消息,订单超时时间仍然是三十分钟,那么延时消息的时间也是三十分钟,当订单创建时间超过三十分钟之后,延时消息就会发送到订单微服务,订单微服务检查此订单的支付状态,如果未支付则修改订单状态为取消,备注取消原因为用户超时未支付。第三个方案我们这边是使用java实现了一个状态机模型,每个状态可以被表示为一个状态类,每个动作可以被表示为一个方法。设置一个定时器监控订单的超时,订单被创建之后,一旦超过三十分钟,就会触发超时规则,开始执行状态转换动作,也就是提前设置好的方法,这个方法就是查询数据库的订单信息,然后判断支付状态,如果为未支付状态,则修改订单状态为取消,备注取消原因为用户超时未支付。

10)什么时候发优惠券?

当新用户第一次使用我们这个产品的时候,我们可以给用户发放一定的优惠券作为欢迎礼。

还可以在节假日和特定活动期间,在节假日、特定促销季节或平台特定活动期间,推出促销活动并发放优惠券,以吸引用户进行预订。如果是用户充值会员,我可以给会员用户提供优惠券,以鼓励他们继续使用平台并享受额外的折扣。还有一种优惠券就是景区和平台直接合作发放,为了推广特定目的地或旅游产品,以鼓励用户选择该目的地或产品。

11)优惠券的成本谁承担?

1.       全平台优惠券:全平台优惠券通常由平台承担成本。平台作为中介,通过发放优惠券来吸引用户在其平台上进行购物或使用服务。平台会根据自身的营销战略和预算,在与商家合作的基础上承担全平台优惠券的成本。

2.       节假日优惠券︰在节假日期间,商家可能会与平台合作发放优惠券,以吸引更多顾客消费。商家和平台可以根据合作协议商定优惠券成本的分摊比例,以达到双方的利益平衡。

3.       特定店家使用的优惠券:特定店家使用的优惠券通常由商家完全承担。这些优惠券仅适用于特定店家的产品或服务,商家通过发放优惠券来吸引顾客光顾自己的店铺。商家将优惠券的成本计入自己的营销费用,并期望通过提高销售量和顾客满意度来获得回报。

12)抢优惠券并发怎么控制

抢券活动中的用户并发会比平时高,系统流量激增,服务器瞬时压力很大,请求的数量会远大于商品库存数量,这个时候就需要确保优惠券不会被超领,首先可以从预防的角度,控制并发问题,确认每个人只能抢恒定数量的优惠券,设置请求频率间隔,每个用户每次请求的有最小时间间隔,或者验证码请求,其次可以设置分时间段领取优惠券,错开高峰期,平衡流量均速。然后解决并发问题可以利用分布式锁,采用redison的分布式锁来解决这个问题,以优惠券的索引加库存数量作为key,用redisclient对抢优惠券请求进行加锁,使用try-catch-finally语句,进行异常处理和资源释放,这样即解决了库存为负数问题,也避免了堵塞的可能性,用户抢优惠券行为每成功一次该类型优惠券数量-1。同时还有一个看门狗机制,会给你当前请求获取的锁不断的续期,直到方法执行完毕,这样就不会出现误删除锁,从而导致资源竞争和冲突。

13)Drools规则引擎的规则存在哪里

我们是这样存放drools规则引擎的文件的,我们这边是存放到数据库中,然后需要在drools配置文件中指定规则文件的具体目录,这样规则引擎才可以在启动的时候,通过配置文件,去数据库寻找规则文件,考虑到规则引擎需要快速读取和实时修改和热部署的要求,我们使用的是redis非关系型数据库存储规则文件,将规则文件转会为字节流文件,使用redis的set存储,key为文件名,value为文件内容的字节文件,这样可实现更新规则文件,自动替换原有的规则文件,简化了代码的编写,也方便了其他同事去更新规则文件的内容。

14)为什么使用ES来做酒店搜索?

因为在拥有大量数据的情况下,搜索效率是一个很重要的事情;而MySql数据库当达到上百万条数据的时候搜索效率会变得很低很低;尤其是MySql在执行的模糊查询的时候,like会触发全表扫描;间接导致like关键字会锁表,也就是只会执行like这条语句,别的工作都会暂停;

遇到这种情况要怎么办呢?有人说用redis数据库,但是redis并没有提供给更丰富的搜索方式;所以就要用到ES;而ES的倒排索引机制和分布式架构,能够快速地执行搜索和聚合操作。它还具有水平扩展能力,可以轻松的处理大量数据,因为去ES分布式架构的特性,可以采用分片的方式来分散数据和负载到不同的节点,提高系统的可靠性和容错能力,并且还可以通过添加节点来扩容,除此之外提供了大量的API支持多种查询类型、模糊搜索、近似搜索、智能提示和高亮显示等。还能对搜索的结果进行实时聚合、过滤、分组等操作它还支持中文分词、拼音搜索等特殊需求,还可以根据地理位置进行排序。这就是我们项目为什么用ES做搜索的原因

15)竞价排名是什么?怎么做的?

竞价排名相当于是一种在线的广告竞价模式。广告主竞相出价购买关键词或者广告位,然后在用户使用搜索引擎进行关键词搜索的时候,他们的广告或者产品能够在搜索结果中展示,也会根据出价的不同,在搜索引擎结果页面显示的顺寻也会有不同。

在我们项目中,刚开始对酒店竞价排名这个功能进行技术选型的时候,有两种选择方案。一种是基于ElasticSsearch来实现,另一种是基于Redis来实现。最后通过项目组讨论,结合这两种技术在数据存储、实时性、排序算法以及数据量和性能方面的对比,决定选用ES来实现酒店竞价排名功能。我们使用了ES中的自定义评分机制fuction_score查询来影响算分,算分越高排名也就越靠前。我们会给这些酒店添加一个标记,然后再过滤条件中就可以根据这个标记来判断是否需要提高算分。比如给酒店的实体类添加一个boolean类型的字段,true为需要加分,false为不需要加分,然后当这个字段为true的时候,通过合适的加权值和加权方式来提高算分,那么当得分提高之后该酒店的排名就会向前排名。

16)拼音搜索是怎么做的?

在我的这个项目中是使用ES的拼音分词器来实现拼音搜索的,他会按拼音对中文文本进行分词,然后我们在创建索引时,定义文本字段的映射。在映射中,我们指定使用拼音分词器来对字段进行分词处理。这样,当我们索引文档时,ES会使用拼音分词器将文本拆分成对应的拼音,并将它们作为单个字进行索引。当用户进行搜索时,将用户输入的拼音关键词传递给ES。ES会使用同样的拼音分词器对用户输入的拼音进行拆分和标记。ES会根据这些拆分后的拼音进行匹配。在匹配时,ES会查找包含对应拼音的文档,并返回给用户。

17)ES数据批量导入如何实现的?

对于批量导入如何实现,在我这个项目中是采用xxl-job的分片广播策略来实现的,在执行这个分片广播策略的任务时,会先获取当前执行器有几个节点,每个节点的下标,然后通过每个节点下标来确认每个节点的起始索引和每个节点的执行条数,确定每个节点的任务后再进行分页查询,然后再进行批量导入es索引库,考虑到程序的执行效率,我这个项目中还采用bulkRequest和多线程来进行一个批量导入。

注意:边界划分:剩余任务不足定义的每页size,则变更size为剩余任务

18)风控系统有哪些功能?如何设计的?

因为游客旅行可能会发布文章,所以会设计这个风控系统对文章内容进行审核,审核首先要创建自己的敏感词库,当游客发布文章先会将文章内容、发送主题进行封装,然后将消息发送给kafka。然后在风控系统监听消息。然后会先调用自己敏感词库使用DFA算法进行审核,审核图片的话需要用到tess4j提取图中的文字然后使用DFA算法进行审核,如果审核不通过就直接将审核不通过的消息发送给游客。如果本地审核成功则需要调用阿里云的审核服务,如果审核不通过则会将涉及到的敏感词存入本地敏感词库并向用户发送审核不通过的消息,如果审核通过则直接给用户返回审核通过的消息。

19)为什么要生成静态页?怎么访问静态页?

如果不生成静态页的话,用户的每次请求都是直接调用数据库,会增加服务器的压力,所以需要生成静态页,以提高网页加载速度,生成静态页用到了一个模板引擎技术(Freemarker),它可以根据自定义的模板将文章内容展示到网页上,通过Minio或者阿里云服务器进行存储,在存储静态页的同时会将静态页的URL存入到数据库中,后续可以通过数据库中存储的URL访问到静态页。

20)订单数据量太大,如何存储?

由于我们的数据格式高度统一,但是数据量很大,所以这里我们采用了水平分库分表,将不同的数据分散到不同的库中,每个库存储的数据都不同,这样就可以将单一库的压力分散到多个库中,从而提升整个数据库的服务能力。

其次我们将订单数据按照下单时间进行分片,每个分片再进行分表,将数据分散到不同的物理数据库节点和物理表中。可以根据订单数量的增长和每个订单数据量的变化,灵活地调整分片和分表的数量和规则。执行订单相关的数据库操作时,ShardingSphere-JDBC 会根据配置的分片规则和分片算法,自动将操作路由到对应的数据库和表中。例如,根据订单ID查询订单时,ShardingSphere-JDBC会根据订单ID的值计算出订单所在的数据库和表,然后发起查询操作。在涉及跨数据库操作的事务处理时,我们使用了ShardingSphere-JDBC 提供的分布式事务功能,确保多个数据库之间的数据操作的一致性。

为了保证数据的高可用,然后我们用ShardingSphere-JDBC实现读写分离,我们是往主库中写入数据,同步到从库,写入时只写入主库,读取时从库读取,来减轻数据库的压力。

最后,对于陈旧的历史数据,我们利用Gzip将其压缩和归档以节省存储空间。然后将其存档到长期存储媒体aliyun中。同时,定期进行归档数据的备份,并建立相应的恢复机制,确保在需要时能够快速恢复归档数据。

21)ShardingSphere-JDBC如何实现分片?

/ShardingSphere-Proxy如何实现分片?

在节假日期间,为了处理海量订单的存储和读取需求,我们采用了shardingsphere-jdbc进行数据分片处理。具体来说,我们将订单号作为分片键,并根据时间范围进行运算,以实现动态分片和负载均衡。

当有客户端发起连接请求时,ShardingSphere-Proxy会接受连接,并创建一个对应的连接会话,负责管理客户端的连接状态,并与后端的分片数据库建立连接。接下来是路由选择,当客户端发送查询请求时,ShardingSphere-Proxy会根据配置的分片规则和路由算法选择目标分片,确定将请求路由到哪个分片数据库上。

在路由选择完成后,ShardingSphere-Proxy会解析客户端发送的SQL语句,并根据分片规则和路由选择结果,对sql语句进行重写,以确保查询可以在正确的分片数据库上执行。接着,ShardingSphere-Proxy会将重写后的SQL语句发送给目标分片数据库执行。它会使用连接会话中的连接信息向数据库发送请求,并将数据库返回的结果存储起来。当所有的分片数据库执行完成后,ShardingSphere-Proxy会将各个分片数据库返回的结果进行聚合,包括合并排序、去重等操作,以确保最终返回给客户端的结果是正确的。

另外,对于频繁读取的订单数据,我们使用了缓存机制Redis将热点数据缓存起来,减轻数据库的读取压力,提高系统的读取性能。为了平衡各个分片节点的负载和请求分发,我们引入了负载均衡器,将请求均匀地分发到各个分片节点,以提高系统的并发处理能力。

同时,为确保分片节点的高可用性,我们设置了相应的故障恢复机制,如数据库的主从同步、集群搭建等,以保证系统在节点故障时的可靠性和稳定性。

22)订单重复提交如何解决?

方案一:每一段时间的订单先存入redis,使用set集合来存储,key为订单内容+订单时间(时间戳设为分钟单位)+订单人,value为订单信息的json数据格式,由于set集合结构和redisTemplate对象中save方法特殊性,在不断更新订单提交时间的同时,保证同一分钟内,重复操作只会生成一个订单技术,然后通过xxljob任务调度中心,开启定时任务,每隔一段时间将redis中的数据解析出来,存入mysql数据库,进行持久化储存。

方案二:在用户创建订单时,前端JS会随机生成一个唯一的字符串Str,在存入到Mysql中时,会先尝试存入到Redis中(Str为key),如果能存入,则说明该请求是首次请求,就会存入到Redis以及Mysql中;如果存入失败,则说明该请求为重复请求,就会拒绝本次请求并返回给前端报警信息。

方案三:对于同一笔订单是不允许同一时间提交多次的,会造成后端代码逻辑错误,从而造成阻塞,本项目采用redisson分布式锁来解决这个问题,在创建订单前为每个订单生成一个唯一标识,这里我们可以采用订单号或UUID为key,在执行订单提交请求之前用redissonclient.getLock()对订单唯一标识进行加锁,只有在获得锁的情况下才可以执行后续操作,使用try-catch-finally语句,首先判断订单表示是否已经存在,即检查是否是重复提交,可以通过数据库查询或是其他存储系统查询,如果订单不存在就进行后续操作。订单处理完成之后,成功就创建订单,不成功就捕获异常,然后释放锁,这样即解决了重复提交的问题,也避免了堵塞的可能性。

23)抢红包如何实现?

简介:这功能主要是针对会员用户与新用户,如果你是刚注册的用户那么就会得到一定的红包,如果你是会员的话那么平台或者商家会在周年庆等节假日或者活动日期根据会员用户的id对这些用户按照一定的规则发放红包给用户(部分红包设置可以与优惠卷一起使用).

我们是这样实现的:首先我们在后台生成一定数量的红包,并确定总金额同时按照规则分配给每个红包,确定每个红包中有金额,同时设定红包过期时间,然后把红包显示在前端页面上,当用户点击抢红包按钮的时候,会把红包的标识符和用户数据传输给后端,后端会校验用户的资格(比如是否登录,是否已经抢过等要求),当审核通过之后后台会按照设定的分配机制对该用户分配一定数量的金额(比如随机分配规则:根据红包金额列表,随机选择一个金额分配给用户。分配金额小于总金额-已分配金额),然后更新红包中剩余金额数据,同时将用户抢到的金额保存到用户账户中,当红包金额(红包个数)抢完后,更新红包状态为已完成,或者在过期时间内没有抢完的,就会把剩下金额(总金额-已分配金额)返回给发红包的并修改红包的状态为已过期.在抢红包过程中,需要考虑并发情况下的数据一致性和竞争条件。使用乐观锁或分布式锁来保证数据的一致性。可以借助数据库的事务或分布式事务来处理并发抢红包时的并发问题。

24)抢红包算法有哪些?

抢红包算法是指在一定规则下,多个用户同时参与抢夺一定数量的红包时,如何公平地分配红包金额的算法。大概有以下几种算法

1.随机分配算法:将红包金额随机分配给参与抢红包的用户。每次抢红包时,随机生成一个金额,并确保这个金额不超过当前红包剩余金额。

2.平均分配算法:将红包金额平均分配给参与抢红包的用户。每次抢红包时,根据红包剩余金额和剩余人数,计算出每个人可分得的平均金额。

3.拼手气算法:将红包金额随机分配给参与抢红包的用户,但每次抢红包时金额的分配不公平,可能有人抢到大额红包,也可能有人抢到小额红包。

除了以上常见的算法外,还可以根据具体的业务需求设计特殊的规则,如根据用户等级、抢红包时间、活动规则等信息进行红包金额的分配。

25)权限系统如何设计的?

我们在设计权限系统时考虑到两方面,一是给用户赋权,二是鉴权。

首先是用户赋权,我们是通过设计权限表来实现的,设计了三张核心表:用户表(User):存储用户信息,包括用户ID、用户名、密码等;角色表(Role):存储系统中定义的角色信息,用于对用户进行分类和组织。一个用户可以拥有多个角色。权限表(Permission):存储系统中定义的具体权限信息,用于对角色或用户进行精细的权限控制。以及三张表之间的关联表:一个用户有多种角色,一个角色至少对应一种权限。

然后是实现鉴权,这边首先是前端的权限校验:当用户登录成功后,前端会发起申请请求,后端会将用户的id以及用户的权限字段返回给前端,然后前端会根据权限字段来对页面功能按钮进行合理隐藏或暴露。然后是我们后端的接口资源鉴权:我们采用的是Spring Security 提供的注解@PreAuthorize,这个注解中会封装鉴权的执行方法,当用户发起请求想使用接口时,该方法会从用户请求头token中获取到用户id,查询数据库得到该用户的角色所对应的权限字符串,并判断该用户是否是拥有使用该接口的权限,并返回true或false,@PreAuthorize(”true”)则通过校验,否则拦截并向前端发出报警。

26)推荐系统如何实现的?

在我们这个项目中推荐系统就是为了把一些比较热门的景点展示给用户,让用户进行浏览和选择。这个功能我们是基于MongoDB和Redis来实现的。首先在发布景点信息时,我们会在MongoDB中进行建档,字段包括id、浏览数、点赞数、评论数以及基础score。同时会使用Redis的Zset数据类型来存储热门景点。当redis中热门景点信息总数不足1000时,直接把该新增信息存入,否则的话会比较该新增景点信息和redis中score最小的景点信息,择大存入。

当用户进行浏览、点赞或评论时,我们会使用KafkaStream统计做实时统计,再交给kafka消费者计算score增量,更新到mongoDB,再同步到redis。这样,当展示景点列表时,从Redis中降序取出景点id并从数据库中进行查询时,就能实现热门景点前排展示的效果

我们也会基于mongodb和es做一个对不同用户推荐不同的内容来实现一个千人千面的效果。首先我们在存入景点信息时,会根据文本介绍以及图片信息通过DFA算法以及tess4j提取出其中的关键字以及标签,并在ES映射中设置关键字及标签字段。然后根据用户近期的搜索关键词以及浏览、点赞、评论的景点信息中的关键词来设计用户模型关键词以及标签,并将用户模型存储到MongoDB中,同时类似热门推荐中的操作,使用kafkastream来完成实时的标签更新及替换。当用户浏览景点信息列表时,使用ES查询景点信息时,遍历用户标签及关键词,与每个景点 信息的进行匹配,匹配成功就增加该景点的score,这样就能实现展示给每个用户不同的景点列表信息。

目录
相关文章
|
机器学习/深度学习 人工智能 编解码
CES亮点:AI赋能与产业创新 | DALL-E 3、SD等20+图像生成模型综述
随着科技飞速发展,CES(国际消费电子展)已然成为全球科技产业的风向标,每年的CES大会都是业界瞩目的盛事。回顾2024年CES大会,不难发现其亮点纷呈,其中以人工智能的深度赋能为最引人注目之处。AI技术的深入应用成为CES大会上的一大亮点,各大厂商纷纷展示了在AI领域的最新成果。
1200 0
|
4月前
|
自然语言处理 Java API
【AgentScope Java新手村系列】(7)子Agent编排
子Agent编排 — SubagentDeclaration 描述子 agent,主 agent 通过 agent_spawn 工具同步/异步委派子任务。
937 0
|
存储 Java 调度
Springboot集成Quartz(任务存储在数据库)
集成quartz实现定时调度,quartz是一个功能丰富的开源的任务调用系统,它可以定义很多job并发执行,支持事务和集群
2167 0
|
监控 数据挖掘 开发工具
淘宝天猫商品详情数据接口采集攻略
本文详细介绍如何通过淘宝天猫商品详情数据接口采集商品信息。首先概述了常用接口(如taobao.item.get、tmall.item.get)的功能,可获取商品基础信息、描述及评价等。接着说明接入准备,包括注册认证、创建应用与申请权限,以及开发环境配置。最后提供采集流程指引,如通过商品链接或搜索接口获取ID,并以Python示例展示接口调用方法,助力开发者高效挖掘电商数据价值。
1633 1
inux CentOS 7 如何进入默认工作目录 [root@localhost ~]
这篇文章讨论了如何在Linux CentOS 7系统中进入默认工作目录。默认工作目录通常是用户的主目录,表示为`[root@localhost ~]`,其中波浪号`~`代表当前用户的主目录。文章可能还包含了如何打开这个默认工作目录的步骤和说明。不过,具体内容没有提供详细信息,通常可以通过打开终端并使用`cd ~`命令来进入默认工作目录。如果需要更详细的步骤或有特定的问题,可能需要查看原文获取更多信息。
|
SQL 关系型数据库 MySQL
Vanna使用ollama分析本地数据库
这篇文章详细介绍了如何使用Vanna和Ollama框架来分析本地数据库,实现自然语言查询转换为SQL语句并与数据库交互的过程。
3128 7
Vanna使用ollama分析本地数据库
|
监控 PHP Apache
优化 PHP-FPM 参数配置:实现服务器性能提升
优化PHP-FPM的参数配置可以显著提高服务器的性能和稳定性。通过合理设置 `pm.max_children`、`pm.start_servers`、`pm.min_spare_servers`、`pm.max_spare_servers`和 `pm.max_requests`等参数,并结合监控和调优措施,可以有效应对高并发和负载波动,确保Web应用程序的高效运行。希望本文提供的优化建议和配置示例能够帮助您实现服务器性能的提升。
1355 3
|
SQL Java Scala
flink-cdc SQL Server op 字段如何获取?
Flink CDC 是 Apache Flink 的组件,用于捕获数据库变更事件。对 SQL Server,通过 Debezium 连接器支持变更数据捕获。`op` 字段标识操作类型(INSERT、UPDATE、DELETE)。配置包括添加依赖及设定 Source 连接器,可通过 Flink SQL 或 Java/Scala 完成。示例查询利用 `op` 字段筛选处理变更事件。
950 1
|
SQL 存储 数据挖掘
深入了解SQLite3命令:小巧强大的数据库工具
SQLite3是轻量级数据库工具,适用于嵌入式设备和数据分析。它提供交互式shell,无需服务器,易于部署。常用命令如`.schema`显示表结构,`.mode`设置输出格式。示例包括创建数据库`mydatabase.db`,创建表`users`,插入数据并查询。注意动态类型系统、性能限制及SQL注入安全。适合轻量级数据存储和管理。
|
资源调度 分布式计算 算法

热门文章

最新文章