分类目录归档:Python

让我们来做个django小项目之二

上篇内容我们算是来了一个开场,创建了我们的项目,最后把数据库也建立完成了,这篇我们主要完成后台数据入库的部分,根据我们之前的思路,如果已经能实时获得每个站点性能信息了,如果能将每次获得信息插入到数据库中,这个就完成了我们的入库部分,这里说一下我们的数据库操作部分,要操作数据库,首先我们要跟数据库建立连接,然后进行常规的CRUD操作,操作完毕后再关闭数据库连接,这是一个基本流程,所以为了提高数据库的操作速度,我们可以把一些常用的操作封装成一个类,以下是我门数据库操作的类代码:

在这个类中我们先定义了__init__方法,指定了数据库连接,用户,端口,用户等信息,接下来是定义了三个方法,分别是建立数据库连接,获取数据内容、更新数据库及最后关闭数据库连接,正题逻辑就是这样,代码没特别的内容。

有了这个数据库类后,我们就可以用上我们之前的pycurl模块去获取每个站点的数据了,每次获取的数据插入到数据库中,因为可能非常多的站点,所以我们要考虑运行效率,所以我们这里使用并发去检查站点数据,采用ThreadPool线程池去实现,全部代码如下:

以上就是我们全部的代码内容,pycurl部分我们不在多解释,不理解的小伙伴可以参考之前的文章,Dummy就是多进程模块的克隆文件,唯一不同的是,多进程模块使用的是进程,而dummy则使用线程,pool.map类似python的map函数,需要二个参数第一个参数是一个函数名,第二个参数是个迭代对象,在这里迭代对象我们是从数据库中直接获取的,至于数据库的数据从哪里来的呢?当然是用户输入的,那下篇我们实现下前端输入页面,让用户自己可以增加要监控的站点,这篇就到这里,喜欢的小伙伴请帮忙转发哟。

 

 

 

站点性能监控demo

上篇我们简单介绍了pycurl的基本使用,在组后我们留了几个问题需要去解决,因为最终我们要实现的是一个页面版的展示所有站点性能的demo, 那这篇就是正式开始我们这个小项目,废话不多说,首先我们创建我们的项目,在命令行模式下输入:

然后进入web_monitor目录中,创建一个app.

创建完成 后我们的目录结构是这样的:

因为数据要需要入库的,所以第一步先设计我们的表结构,也就是我们的Model文件, 进入到sitemonitor目录下,打开models.py文件,写入:

这个文件我们定义了表结构和字段,按上篇我们获取的内容,我们存储的内容有http_code, dns_time,connect_time, pretransfer_time, starttransfter_time,total_time, speed_downlaod字段,url,port,phone这三个字段是为用户输入表单时准备的,这三个后续会用到的时候再说,这里只需要注意因为获取的数字很多都是小数,所以像dns_time我们使用了models.DecimalField字段类型,这个字段类型有2个参数:

max_digits:数字允许的最大位数

decimal_places:小数的最大位数

其它字段类型解释如下:

models.CharField:字符串字段 ,max_length是必须的参数。

models.SmallIntegerField :   数据库中的字段有:tinyint、smallint、int、bigint.   类似 IntegerField, 不过只允许某个取值范围内的整数。(依赖数据库)

然后保存退出,打开site_monitor/settings.py文件,修改如下行:

加入的行我已加注释,不多解释,接下来我们创建数据库表,运行:

接着运行:

这时候我们的库表结果就建立完成了,那这样前期准备工作就全部完成了,下一篇我们开始写后台实现数据实时插入库。

python+pycurl检查网站性能指标

对于一个网站运维人员来说,一个网站的性能好坏是大家非常关心的内容,我们知道衡量一个网站的好好多方面,但对运维人员来说站点的性能指标是我们比较关注的内容,从用户角度来说,最直观的感受就是用户户输入网址后站点内容打开速度的快慢,那从一个用户发起请求到服务器,然后服务器响应提供给数据给客户端,了解http协议的小伙伴应该知道,这中间要经过多个步骤才能实现,所以说一个站点如果出现访问速度上的问题,要从整条链路上去查原因而不能只看某一方面,访问示意图如下:

client-server-architecture

在这个访问过程中我们会关注以下几个指标:

  • DNS解析所消耗时间
  • 从建立连接到准备传输所消耗的时间
  • 从建立连接到传输开始消耗的时间
  • 传输结束所消耗的总时间
  • 平均下载速度
  • 返回的HTTP状态码

通过对以上几个指标的实时监测,当出现问题时就可以快速分析定位问题, 那如何获得这些数据呢,下面就要用到我们的pycurl了,Pycurl包是一个libcurl的Python接口,它是由C语言编写的,速度非常的快,下面看看我们的具体实现:

 

脚本里我只获取了一些比较核心的指标,当然pycurl功能不止这些,如果需要它还可以获取更细致的指标,例如:平均上传速度,HTTP头部大小等。有需要的小伙伴可以自己再研究下,脚本不做多解释了,关键行我加了注释, 最终获取的数据写入到了文本里,可以定时执行这个脚本来实时获取最新数据,这个脚本对要求不高的场景使用没啥问题,但对我们自动化运维来说只迈出了第一步而已,因为最好的方式是通过一个web页面去实时展示各个站点的情况,便于只观的观看,那要实现一个基本的站点,有几个问题我们需要我们思考去解决:

  1. 获取的数据要保存下来,就是有一个入库操作
  2. 随着站点的增加,后台运行,为效率考虑必须要用并发执行
  3. 前台方面:入库的数据要在前台展示,就需要用ajax
  4. 前台展示的页面要能主动自动刷新
  5. 前台入口需要提供一个用户添加url地址的表单
  6. 当然为好看,我们也要使用boostrap等类似的前端框架。

做完这些才算是基本完成我们最终的目标,在后续的文章里我们会逐一完成上面任务,喜欢的小伙伴还请转发,谢谢。

用Data-pipeline模式将nginx日志存储到elasticsearch中(续)

接上篇的内容,这篇我们要解决第二个问题,就是如何将我们转换完成的json数据发送到es中去,上篇提到了要存储到es中,我们要使用kafka来做消息队列,实现发布和订阅消息流模式,因为涉及kafka内容,所以我们先说一下Kafka的一些基本知识,然后再看代码不然一是一头雾水。

kafka介绍:

1、什么是kafka?

2、kafka特性

3、kafka解决了什么问题?

4、kafka的一些概念和名词

除了上面的一些内容外,我也谈一下我自己的一些理解,为什么kafka变得如此流行,很大程度上因为的特性决定的,

比如数据的聚合,怎么理解,就是我们可以把产生数据的系统就做生产者,有多少生产者无所谓,只要建立对应的topic,把数据发送到这个topic中就可以,如果有不同部门向要相同的数据,就去订阅这个topic即可,这样最大的好处是使我们系统结构清晰,同时能减少我们很多重复的工作。

另外一个重要的特性就是高并发性,并支持分布式部署,在一个繁忙的系统中,产生的日志或者其它数据是非常庞大的,要对这些数据进行处理,必须要一个高吞吐量、低延迟的处理系统,Kafka正好满足这个需求,每个topic可以建立一个或多个分区,每个分区你可以简单理解为一个公路上的多个车道,每个车就是数据,因为车道多所以它可以加速数据的传输。

经过上面的介绍,相信大家都对Kafka有了一个基本的了解,那接下来回到我们上面的问题,看如何在我们这个例子中使用:

1、安装kafka,这个因为比较简单就不在费篇幅写了。

2、安装完毕后建立一个topic, 命令:

bin/kafka-topics.sh –create –zookeeper 127.0.0.1:2181 –replication-factor 1 –partitions 1 –topic www_logs

3、安装:pip install kafka-python

4、实现生产者类:

代码不是很多,先定义了初始化类的__init__方法,需要两个参数,一个就是broker这个没什么可说的,value_serializer的意思是用于将用户提供的消息值转换为字节,send_page_data()方法是将数据发送给对应的topic。

5、修改下上篇中的脚本,使其实现转换后发送到kafka中,修改如下:

增加的行都已注释,不多解释了。

到这我再梳理下我们都干了什么。

第一,我们实现了access.log日志的实时读取,并传唤成json格式。

第二,我们讲转换完毕的数据发送到kafka中,topic名词是www_logs

以上我们都已完成,接下来的问题是要怎么把数据存储到es中,不过先别急,先让我们验证下我们之前的工作是否正确吧,要验证是否可以从topic中读取数据,我们还需要一个消费者程序,为简单验证,我这边实现一个最简单的消费者程序,如下:

就是从topic中读取数据,然后打印,如果没问题,就可以证明这条通路是通的,首先在一个终端运行,我们的日志分析程序,结果如下:

行太多,我只截取了2行,因为我们有打印,说明转换是没有问题的,但是否发送到了kafka呢,我们在另一个终端运行我们的消费程序,结果如下:

可以看到我们消费者成功的从kafka中取得了数据,说明这条通路我们已经打通了,这条数据流已经没有问题,那接下来就剩下最后存储到es中的问题了,我们后续再接续,这篇已经很长了。

 

 

 

用Data-pipeline模式将nginx日志存储到elasticsearch中(1)

做运维的小伙伴应该都知道nginx日志的重要性,一般出现访问问题,我们可能第一时间要去看日志去分析问题,但除了协助我们排查问题外,如果对nginx日志进一步分析可以得到更有用的数据,例如可以监控某站点的http状态码、PV,UV情况,request_time和response_time等,如果辅助其它工具进一步分析可以预防一些安全问题,比如同一个IP的访问某页面超出了限制,我们可以设置策略发现后可以自动拒绝有危险的IP访问,这也是我们经常说的防刷功能,今天要跟大家分享的是如何将nginx日志存储到es中,存储的目的当时是为了更好的分析它,大家都知道,如果要存储到es中,数据必须是json格式的,但如果当前日志不是json格式的就需要进行一个转换,要把每行数据转成json格式的这里有几个问题要明确:

首先,access.log是不断增长的,这就需要有个程序能实时读取新的日志进行转换,这是第一个要解决的问题。

其次,对转换完的数据我们能不能直接存储到es中,答案是不建议,因为如果转一次存一次,在程序中我们势必要判断每次存储是否成功,在高并发的网站中日志的产生量是非常巨大的,这样一来会影响整体的效率,那怎么办?在这种情况下,最好的解决办法就是用消息队列的方式去解决,这里我们选择kafka,这个后续会说。

根据上面的内容大家可以看到其实在分析nginx日志的过程就是一个数据流的处理,这也是我们标题所说的data-pipline,pipline故名意思就是管道的意思,加一个data就是一个数据管道,我们就是要建立一个这样的管道将数据源源不断的产生出来,就像水管的水一样。

因为要解决的二个问题,今天我们先解决第一个,先实现access.log实时读取和转换成json格式,先看我们的access.log的文件内容:

 

划重点了,请看代码:

运行结果:

 

 

脚本整体逻辑是先将行日志转换成一个字典(parse_log_line()函数),然后将字典转成json格式(show_entry()函数),最后follow函数是开始从尾部读取日志文件注意seek(0,2)参数是2从文件底部读取。

写到这我们第一个问题就算是解决了,接下来的工作就是如果把数据传给kafka了,因为kafka本身就是一块比较大的内容限于篇幅我们下次继续,多谢各位观看,如果觉得还不错,还请帮转发。