定时同步数据的任务优化

前言定时任务在系统中并不少见,主要目的是用于需要定时处理数据或者执行某个操作的情况下,如定时关闭订单,或者定时备份。而常见的定时任务分为2种,第一种:固定时间执行,如:每分钟执行一次,每天执行一次。第二种:延时多久执行,就是当发生一件事情后,根据这件时间发生的时间定时多久后执行任务,如:15分钟后关闭订单付款状态,24小时候后关闭订单并且释放库存,而由于第二种一般都是单一数据的处理(主要是指数据量不大,一般情况下只有一个主体处理对象,如:一个订单以及订单中的N个商品),所以一般情况下第二种出现性能问题的几率不大(不代表没有),所以本文主要是针对第一种定时任务来进行优化,而且主要是针对数据同步或者传递数据来进行优化,而优化的方式也是根据实际项目中的情况在不同阶段进行优化的 第一阶段第一阶段属于原始阶段,逻辑也最为简单,由于同步分为数据同步和传递数据,而且2种的需求各不一致(主要是在于是否允许丢失),所以分开分析 第一种类型:传递数据由于传递数据可以允许丢失,常见的场景如调用凭证推送(常见于接口需要暴露给第三方,为了安全性,可以定时推送调用凭证来保证接口安全性),消息推送(订单消费成功后推送消息,由于可能推送失败,所以需要进入定时任务进行重试,但是因为消息实时性,所以重试到一定次数后放弃重试) 传递数据在第一阶段设计非常简单,定时推送,有限的错误次数,同步成功后修改状态,同步失败后对失败次数+…

centos7搭建EFK日志分析系统

前言EFK可能都不熟悉,实际上EFK是大名鼎鼎的日志系统ELK的一个变种 在没有分布式日志的时候,每次出问题了需要查询日志的时候,需要登录到Linux服务器,使用命令cat -n xxxx|grep xxxx 搜索出日志在哪一行,然后cat -n xxx|tail -n +n行|head -n 显示多少行,这样不仅效率低下,而且对于程序异常也不方便查询,日志少还好,一旦整合出来的日志达到几个G或者几十G的时候,仅仅是搜索都会搜索很长时间了,当然如果知道是哪天什么时候发生的问题当然也方便查询,但是实际上很多时候有问题的时候,是不知道到底什么时候出的问题,所以就必须要在聚合日志中去搜索(一般日志是按照天来分文件的,聚合日志就是把很多天的日志合并在一起,这样方便查询),而搭建EFK日志分析系统的目的就是将日志聚合起来,达到快速查看快速分析的目的,使用EFK不仅可以快速的聚合出每天的日志,还能将不同项目的日志聚合起来,对于微服务和分布式架构来说,查询日志尤为方便,而且因为日志保存在Elasticsearch中,所以查询速度非常之快 认识EFKEFK不是一个软件,而是一套解决方案,并且都是开源软件,之间互相配合使用,完美衔接,高效的满足了很多场合的应用,是目前主流的一种日志系统。EFK是三个开源软件的缩写,分别表示:Elasticsearch…

记一次MySQL迁移并从MySQL5.6升级到5.7后查询慢了几十倍的问题

起因因为生产环境数据量越来越大,客户越来越多,项目功能也越来越多,项目本身也越来越多,导致之前的服务器内存、硬盘都已经渐渐的不够用了,当时出现了2种解决方案,增加服务器配置和新购服务器,但是就算是新增硬盘,也需要对数据库进行迁移,所以就采用了新购服务器的方案,并且因为之前是高效云盘,出现过IO占满的情况,所以对于新购的服务器采用了SSD硬盘,理论上速度会飞起来了,实际上我在新服务器上安装MySQL5.7,因为听说MySQL5.7性能提升了N倍,还支持json(虽然对我们没什么用),但是毕竟MySQL8已经出来了,说明MySQL5.7也肯定稳定好了。so,就找了个夜深人静的晚上偷偷的吧数据库迁移过来了,然后开启慢查询日志,限制为5秒,于是开始各种测试,然后查看了一下慢查询日志,一堆慢查询日志,所以有了这篇文章,为什么会出现这么多慢查询,以及如何解决 开始排查将慢查询SQL拿出来,发现主要的慢查询SQL都是链表查询的语句,也就是说查询语句本身非常复杂,所以就把SQL语句放回之前的数据库执行,发现之前的数据库都是不到1秒就查询出来了,而在新的数据库上最慢能达到140多秒,这明显就不正常了,毕竟新的MySQL服务器无论是CPU、内存、还是硬盘相对于以前的MySQL服务器来说,都是好了不止一星半点,如果说性能差不多还能接受,但是一下子慢了这么多,就明显是有异常了,于是开始挨个排查 排查第一步:…

使用monit监控服务进程和硬盘以及自动重启进程

需求需要服务器运行的程序在被意外杀死时,能自动重启,同时提醒我程序发生过重启。在服务器硬盘使用量达到一定比例的时候,提醒迁移数据或者清理无用的日志文件,所以需要一个服务器的守护程序(能在centos上运行),要求轻量简单占用少,根据上面的需求,找到了supervisor和monit2款软件 supervisor 和 monit的对比因为主要是要满足以上我们的需求,所以我们根据实际需求来对比,而不是完全对比软件本身 进程守护supervisor: 优点:采用托管的方式守护,一旦进程异常能马上检查出来,可以指定目录,对启动命令本身修改不大 缺点:只能启动前台进程,一旦supervisor发生重启会再次启动进程,导致进程再次被启动(不知道有没有办法避免,) monit: 优点:有基于pid文件和正则匹配的检查进程,不会导致进程重复启动 缺点:通过定时检查的方式检查进程,存在一定延时,另外启动命令必须要包含完整的路径 提醒supervisor:需要使用第三方插件才能实现邮件提醒功能,本身并不支持邮件提醒 monit:原生支持邮件提醒功能 磁盘监控supervisor:本身只是为了守护进程,所以需要第三方扩展才可以监控磁盘 monit:原生支持磁盘监控 轻量级占用少supervisor:基于Python开发,轻量级 monit:轻量级 其他2款软件都提供了网页管理的功能,…

记一次ajax的JSESSIONID 变化解决、非跨域变化

前言某一天测试提了一个bug,系统进入到某个页面中后,出现登录失效,不管怎么样,只要进入这个页面再点击其他链接就会去到登录页面,测试环境没有问题。 开始解决第一步:怀疑代码问题因为测试环境没有任何问题,所以怀疑是代码本身的问题,于是在本地测试,发现本地没有问题,于是重新打包部署到正式服务器测试,发现还是出现异常。 第二步:确认为何会登录失效因为代码和测试环境与本地都是一样的,所以怀疑是数据原因导致登录失效,所以在本地将配置切换到正式环境,发现本地还是没有任何问题,排除这一问题,同时后台也没有任何异常产生,最终追踪到页面,发现页面发出的ajax请求的JSESSIONID 发生了改变,于是开始排查JSESSIONID 为什么会改变,百度到了2种原因: 一、response调用了reset方法导致登录失效二、ajax跨域导致登录失效首先第一个,如果是因为调用reset方法导致登录失效,那么所有的环境理论上都会登录失效,但是为了保险起见,还是检查一下,最后发现并没有地方调用reset方法,所以排除此项。于是检查第二个,但是整个系统并没有跨域,但是为了保险,还是将网上说的方法在ajax请求中添加 beforeSend: function(xhr) { xhr.withCredentials = true; } crossDomain:true, 加上之后发现还是不行,于是以上2种原因被排除 第三步:…

通过Maven profile实现环境切换,快速部署到正式环境

前言在开发工作中存在多个环境:开发环境、测试环境、正式环境(生产环境),而每个环境的MySQL、Redis、Rabbitmq、ElasticSearch等配置各不相同,所以每次开发完成部署或者更新都需要手动改变配置文件,尤其是当使用jenkins等相关自动化编译部署的工具的时候,必须要先修改配置文件再上传代码,否则更新就容易出错。解决这个问题常用的方法有:一是通过Git分支,不同环境不同分支,因为配置文件很少修改,所以一般来说合并不会出现问题,另外就算修改了,在提交代码的时候手动合并一下也就可以了。二是通过maven profile,也是本文主要介绍的方式,maven profile方式有个弊端就是每次修改配置文件就需要修改所有的配置文件,好处就是不管什么分支,配置文件都是相同的(在没有修改配置文件的情况下),不用担心切换分支导致环境异常等等。git和maven profile各有优缺点,具体采用哪种可以根据实际情况采用 开始使用Maven profile创建对应文件夹使用maven profile需要给不同的环境创建不同的配置文件夹,比如我的项目主要有测试环境和正式环境,所以在resources文件夹创建了2个目录dev(测试环境)和formal(正式环境),同时把配置文件application.yml放入2个文件夹,修改dev的application.yml服务端口为8081,formal的application.yml的服务端口为8080,具体结构如下图 修改pom.xml文件首先在pom.xml中创建测试环境和开发环境节点…

ElasticSearch优化会员列表搜索

ElasticSearch简介ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便,维基百科、Stack Overflow、Github 都采用它 为什么使用ElasticSearch当一个系统的搜索非常复杂,需要关联多张表、拥有多种条件来进行查询时,数据库处理起来无疑会很慢,当数据少的时候可能还不明显,但是一旦数据多了,数据库就会被严重拖慢,就算使用索引以及对SQL语句进行优化,可以优化的空间也很少的情况下,那么就可以考虑使用搜索引擎来优化搜索了,Java开源的搜索引擎有很多,比如Lucene、ElasticSearch、Solandra、Nutch等等,具体选用哪种引擎可以根据不同的引擎的特性来选择,而我是基于引擎本身特性、实施难度、学习开发难度、速度综合来选择的,当然ElasticSearch对于我们来说不一定是最优的,但是技术解决方案永远都没有最优的,只有差不多合适的 安装ElasticSearch因为服务器是用的centos7,所以这里的安装都是基于centos7的,另外ElasticSearch需要jdk 8的支持,所以如果还在用Java8一下的可以考虑更新一下了,或者同时安装一个Java8的JDK 下载ElasticSearch wget https:…

Rabbitmq延迟队列实现定时任务

场景开发中经常需要用到定时任务,对于商城来说,定时任务尤其多,比如优惠券定时过期、订单定时关闭、微信支付2小时未支付关闭订单等等,都需要用到定时任务,但是定时任务本身有一个问题,一般来说我们都是通过定时轮询查询数据库来判断是否有任务需要执行,也就是说不管怎么样,我们需要先查询数据库,而且有些任务对时间准确要求比较高的,需要每秒查询一次,对于系统小倒是无所谓,如果系统本身就大而且数据也多的情况下,这就不大现实了,所以需要其他方式的,当然实现的方式有多种多样的,比如Redis实现定时队列、基于优先级队列的JDK延迟队列、时间轮等。因为我们项目中本身就使用到了Rabbitmq,所以基于方便开发和维护的原则,我们使用了Rabbitmq延迟队列来实现定时任务,不知道rabbitmq是什么的和不知道springboot怎么集成Rabbitmq的可以查看我之前的文章Spring boot集成RabbitMQ Rabbitmq延迟队列Rabbitmq本身是没有延迟队列的,只能通过Rabbitmq本身队列的特性来实现,想要Rabbitmq实现延迟队列,需要使用Rabbitmq的死信交换机(Exchange)和消息的存活时间TTL(Time To Live) 死信交换机一个消息在满足如下条件下,会进死信交换机,记住这里是交换机而不是队列,一个交换机可以对应很多队列。 一个消息被Consumer拒收了,并且reject方法的参数里requeue是false。也就是说不会被再次放在队列里,被其他消费者使用。 上面的消息的TTL到了,消息过期了。 队列的长度限制满了。排在前面的消息会被丢弃或者扔到死信路由上。 死信交换机就是普通的交换机,只是因为我们把过期的消息扔进去,所以叫死信交换机,…