收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 

交流首页 » 软件设计专版 »日志服务架构设计和实践  提现最快的斗地主游戏
发表人 内容
shine333a
[头像]

交流经验:
总积分:100
级别:普通会员
注册时间: 2013-12-25
文章: 7
离线

本文地址:http://www.panxinet.com/forum/posts/list/14641.html
文章摘要:日志服务架构设计和实践 ,农机配件他人忖道,难以预料天资之城。

又拍云作为一家 CDN 服务提供商,每天产生 50T 左右的日志,数量庞大、种类繁多,不论是公司内部,还是客户,对日志都有需求,而且需求都不尽相同。
所以,我首先谈一谈,为什么又拍云需要一个强大的日志系统,主要有三个原因:
首先是为用户提供日志归档的服务,日志根据不同的服务名可提供给用户下载,包括在又拍云后台上可以看到的服务,比如用户想了解自己的服务今天访问最热门的是哪些资源等。
其次是提供近乎实时、多维度的日志分析,包括问题排查,并对接到内部报警系统,这点对又拍云平台的稳定性来说非常重要,比如某个用户的源站网络出现问题,我们可以通过监控系统和内部的服务,将日志给到报警系统实现报警,从而可以通知用户。
第三是日志离线分析功能,可以进行复杂的数据模型计算分析,提供包括细化到每一个省份、城市,定期生成的报表,用户可以了解自己的服务在各个城市的访问情况。
 
又拍云的日志都是通过 CDN 边缘节点的服务产生,服务基于 ngx_lua。ngx_lua 是 OpenResty 的一个核心组件,它将 Lua VM 嵌入到 Nginx 当中,极大地扩展了 Nginx 的能力。
这里介绍一下又拍云 CDN 代理层的服务全部是基于 OpenResty / Nginx 开发的,我们在 Nginx 的优化和二次开发方面投入了大量的精力。
这些日志在边缘节点进行一定的缓冲后,通过公网上传到数据中心的日志服务代理层。因为 CDN 节点分布在全国和海外一些地区,如果每一个机房都到数据中心建传输网络,这个成本比较大,所以这里都是走公网传输。
数据中心日志代理这层使用的是基于 OpenResty / Nginx 构建的一个服务,这层主要是由 LVS 进行四层的负载均衡,所有日志都会均摊到这个集群中的每台机器。这层还会根据日志类型,比如是某个定制的大客户的日志、内部人员使用的日志等,将日志进行一致性哈希,保存到不同的 Kafka topic 。
日志会在 Kafka 集群里面进行暂存。在 Kafka 后面连接着成百上千个日志消费者(包括公司部门和客户),不同的消费者会消费不同的 Kafka topic,它会根据不同的需求,将日志转换成用户所要的格式。
潜在的两个问题
在日志服务过程中,可能会遇到些许问题,这里仅列举了两个问题,当然不止这两点,也存在一些其他值得关注的问题。
问题一:上传问题——由于 CDN 的特点,CDN 的边缘机房部署在全国各地和海外,通过公网上传日志如果遇到部分网络不理想的情况,就会上传失败、丢失。
问题二:日志消费赶不上生产的问题——上传成功,都保存在 Kafka ,但是日志消费者消费能力有限的时候,会导致 Kafka 队列发生堆积。
机房掉电也是很严重的问题。不过又拍云的 Kafka 集群所在的机器装备了双电源,保证它至少在 99.9999% 的情况下,不会出现掉电影响服务。
下面我针对这两个问题,聊一聊又拍云的解决方法。
日志上报方案:解决日志上传问题
我这里说的“日志上报”,指的是又拍云针对 Nginx 日志格式的上报方案。
第一种是通过脚本周期性地向 Nginx 发送信号进行日志切割,然后把日志归档上传。这种方式有个弊端,Nginx 是一个基于事件循环来展开工作的,它最大的敌人就是阻塞,Nginx access.log 目前写磁盘采用的是同步的方式,而且经过了文件系统,极有可能哪个文件系统或者磁盘抽风,整个进程就卡住,导致这个进程内的所有请求一段时间内会处在“饥饿”的状态,影响到它的工作。这种方案看起来显然不是特别完美。
第二种是利用 Nginx 在 1.7.1 版本所支持的直接将产生的 access.log 发到外部的 syslog 组件的方案,这个方案存在一个缺点是如果发送失败日志就会直接丢失,所以也不是特别符合我们的需求。
考虑到又拍云的服务所产生的日志数据相对比较复杂,直接用 Nginx 的 access.log 是不能很好地描述这些日志数据,因此我们采用了以下的方案:

CDN 边缘机房引入单独的 log agent 服务,由它对接数据中心的日志代理层,即我们的 CDN 边缘服务不是直接发到日志代理层的;
在 log agent 内置 disk queue;
CDN 边缘服务引入基于 Nginx 所写的日志发送方案: lua-resty-logger-socket,将日志发送到本机的 log agnet (127.0.0.1)。

lua-resty-logger-socket (http://www.panxinet.com/440/cloudflare/lua-resty-logger-socket)是 cloudflare 针对日志发送的开源方案。该库有一个核心的内存 buffer,它会把上传所提交来的日志数据全部暂存起来,buffer 的内容只会在达到一定大小(flush_limit)之后才将数据冲刷出去,如果发送失败,内容不会被丢弃;如果缓冲的数据大小超过一个硬性值(drop_limit),那么当前的日志会被丢弃。
这个库是基于 nginx_lua 的 Cosocket 技术,Cosocket 通过利用 Lua coroutine 的 yield / resume 特性,完美结合了 Nginx 的事件框架,因此是百分百非阻塞的,这避免了 access.log 写磁盘带来的阻塞问题,和又拍云的 CDN 服务的软件架构非常契合。
接下来日志就到了边缘的 log agent 组件,我们内部称之为“logger”,接收 CDN 边缘服务所发来的日志并进行转发。其实它做的事情很简单,周期性地把日志转发出去,如果网络质量相对比较理想,这些日志只会被短暂地缓冲在内存当中。而如果网络出现异常,内存里的日志会越来越多,当超过某个阈值的时候,日志会自动加入到 disk queue ,这是一个基于文件系统的先进先出队列,当需要转发日志的时,会优先处理在内存和磁盘中排队的日志数据。
如果网络一直很差,日志一直堆积,甚至本机磁盘都不够放,那这个问题就太严重了。这种情况下因为毕竟磁盘容量有限,所幸我们有完善的报警机制,基本上只要出现问题我们立刻就会发现,然后运维和研发会去介入并解决问题。
通过这套机制保证日志即使在网络情况不理想的时候也不会被丢弃。如此,就解决了上面的第一个问题:公网网络不理想的情况下,日志上传不上去,出现丢失的问题,CDN 边缘机房日志上报可靠性得到了保障。
自研 Morgans 系统:让“日志消费”跟上“日志生产”
又拍云的日志种类繁多,包括内部使用、客户使用或者通用的等,需求也不尽相同,所以需要一个通用的日志消费者(包括需要调用日志的公司部门和客户)框架,避免重复劳动,满足不同的需求,基于此,又拍云自研了 Morgans 项目 。
又拍云没有采用开源的日志解决方案,有几个具体的原因:

Logstash 使用了 JRuby 作为插件编写语言,而 JRuby 对资源的消耗比较重;
Logstash 本身存在不少缺陷,容易踩坑;
某些业务场景十分复杂,例如需要适配客户的 FTP 服务器;或者某些客户的服务器需要先进行鉴权;又或者日志需要进行分类和打包;
Mozilla Heka 项目多年未更新,许多问题也得不到修复;
自行设计能够更加贴近业务需求,更加轻量,即使出错也能够快速定位解决。

目前 Morgans 系统已经接管了又拍云所有日志定制和内部监控数据的处理,消耗的 CPU 、内存均比较少,稳定且基本无害。
容器化:解决日志生产和消费的思路
如果日志到 Kafka 这一层没有问题,但日志消费者不给力,这会直接导致了日志数据无法及时传递到下一层,破坏了整个系统近实时的传输转发能力。如何增强消费能力?消费者在设计上需要支持水平可扩容,才能从容应对日志量突增的情况,避免服务可用性降低。
如果新增一种消费者程序或者扩容时,需要提前申请物理机、人工推送服务上线、部署对应的监控报警程序等,全部弄完可能一天的时间已经过去,但是问题还是没有解决,整个操作周期很长,如果是紧急的情况,可能会带来不少的损失。
相比之下,使用容器云平台的优势就非常明显:

资源池化,需要多少 CPU 、内存就配置多少;
拥有故障转移能力,弹性伸缩;
运维成本降低,只需要在网页上配置一些东西,整个服务就布上去了;
自带监控报警,目前对接到了 Slack,如果服务挂了,会推送消息告知什么原因使容器的程序挂掉了。

这篇文章被编辑了 1 次. 最近一次更新是在 2019-03-06 11:50:02


推广链接
精品视频课程推荐

Java Web开发理论部分视频教程
系统掌握开发实际的Java Web应用所需的理论知识和技能(Servlet、Jsp、JavaBean、TagLib、EL、JSTL、MVC模式、连接池DataSource、JNDI等知识)。涉及项目:在线投票计数、在线人数统计、登录检查、购物车、商品管理、非法字符替换等多个随堂演示小应用。

Spring3开发实战-独家视频教程
从零到精通Spring3的开发知识;IoC/DI的思想、IoC/DI的运行流程、IoC/DI的开发指导、AOP的思想、AOP的运行流程、AOP应用的设计、Spring对JDBC和Hibernate的支持、Spring的事务、SSH的集成应用

深入浅出学Spring Web MVC视频教程
系统、完整的学习Spring Web MVC开发的知识。包括:Spring Web MVC入门;理解DispatcherServlet;注解式控制器开发详解;数据类型转换;数据格式化;数据验证; 拦截器;对Ajax的支持;文件上传下载;表单标签等内容;最后以一个综合的CRUD带翻页的应用示例来综合所学的知识

 
交流首页 » 软件设计专版
Message 快速回复

前往:   

关于我们 | 联系我们 | 用户协议 | 私塾在线服务协议 | 版权声明 | 隐私保护

版权所有 Copyright(C)2009-2012 私塾在线学习网