typecho除了首页其他页面404

今天在对typecho做迁移时,发现typecho除了首页之外的其他页面全部404。

解决办法如下:
把nginx虚拟主机的配置文件中的
include enable-php.conf
修改为
include enable-php-pathinfo.conf

重启nginx后问题解决。

今日头条新闻推送系统实践

推送系统作为头条核心系统。

内容简介

今日头条作为业界领先的个性化资讯APP,推送系统能够及时、准确的给用户推送个性化消息、时效性资讯、系统消息,应用消息等,并且推送是用户拉活的最重要手段,推送系统作为头条核心系统,我们不断进行迭代优化升级,下面我会从系统架构和客户端两方面进行介绍。

系统架构:

整体架构图:

20170206001.png

系统简介:

推送生产者:

  • PCMS 推送运营系统(Push Content Management System):每天会有大量的抓取文章进入推送候选,运营同学对推送候选文章进行筛选、预处理(选人群、标记地址位置、优化标题和简介、设置推送level等),如果是全国推送和运营活动推送,会直接调用推送系统进行推送,对于个性推送的任务,由PPS系统进行推送;
  • PPS 个性化推送系统(Personalizaed Push System):根据用户profile和文章profile进行计算,生成 调用在线推送系统进行推送;
  • LiteAPP 小应用(Lite Application):主要是一些程序化推送,包括股票涨跌幅、私聊、系统消息等;

推送核心服务:

  • OpenService 推送系统开放平台:提供对外服务统一接口,对推送任务进行鉴权、任务过滤、任务分发;
  • PJobDB 推送系统任务信息存储:用于任务聚合,实时统计,离线计算,数据挖掘等;
  • LogicCenter 推送系统逻辑处理中心:接收推送任务,进行设备过滤,频率控制,通道选择,数据流输出等;

推送设备服务:

  • TTDeviceService 头条设备服务:用户设备的基础信息
  • PDeviceService 推送系统设备服务:推送系统设备信息、通道个性化选择等;
  • DeviceMongoDB 推送系统核心设备存储

核心模块简介:

OpenService:推送系统开放平台:

流程图:

20170206002.png

模块简介:

  • 用户鉴权:采用<用户、应用、推送范围(单播、组播、广播)、推送等级(强推、正常推)>进行判断,支持根据用户、应用进行、推送范围进行降级;
  • 任务分发:根据推送系统内部设备的分片把一条推送任务放大或放到指定任务队列,推送系统使用的任务队列采用Redis,针对强推,会优先插入到队列首部进行推送;

LogicCenter 推送系统逻辑处理中心:

模块架构:

20170206003.png

模块介绍:

  • 在推送系统内部,整个推送流程从设备存储、任务分发到消息处理都是根据设备id进行哈希分片,在逻辑上划分成N套独立的逻辑单元,减少核心频控逻辑加锁,提高CPU利用率,减少IO等待,在保证服务稳定性的前提下最大限度的提升单位时间内系统的吞吐量。
  • Fetcher:数据捕获,采用BLPOP,从Redis队列里阻塞读取推送任务,获取推送任务后,进行任务解析与规则过滤,构造MongoQuery,从推送设备MongoDB中获取数据,同步写入频控模块内存队列;
  • Filter:频率控制,采用开放地址哈希数据结构,共享内存作为存储,主要包括<设备,消息>维度去重,<设备,消息量>分小时级别、天级别维度频控,按照强推、正常推送等因素进行不同处理,CPU密集型运算,通过内存队列与Fetcher进行解耦,通过频率控制设备数据进行通道分发,根据设备不同的推送渠道,放入不同的Sender内存队列;采用共享内存进行存储,主要考虑因素在于服务重启数据可以持久化,避免频控数据丢失带来的推送体验问题;
  • Sender:推送通道,目前头条推送系统有5种推送渠道:LPush(长链接推送)、MiPush(小米推送)、UPush(友盟推送)、APNS(iOS系统推送)、Poll(轮询推送),每种推送通道有多个独立的worker并行消费内存队列数据,构造不同数据类型,批量、压缩、加密推送到同的通道服务器端进行消息处理;
  • DataCollector:数据收集器(图中未画出),一个RPC本地服务,通过GoRPC进行调用,主要用于频控数据、发送数据的收集与上报,应用数据监控等基础服务,作为独立模块的主要原因在于避免LogicCenter模块重启导致数据丢失;

推送设备服务:

  • 推送设备:推送设备基础信息存储与更新,用户设备扩展属性,包括:用户插件、活跃程度、用户地域、推送开关、推送通道等,主要数据来源头条设备服务基础信息,地理位置服务、用户配置系统等;
  • 推送配置:根据用户设备和推送系统特性,进行黑白名单过滤,版本控制,配置下发等功能,支持推送通道容灾降级;
  • 推送多通道与个性化:目前接入推送系统会开启主备双通道,根据用户设备信息、活跃程度、到达率、点击率、安装设备等一系列因素实时计算出用户个性化的最佳主备双通道,动态切换,确保最佳到达率和推送体验;
  • 智能唤醒:针对长链接类型的推送通道开发了一套消息智能唤醒功能,只做应用唤醒与通道拉活,并且根据唤醒回执数据实时计算、切换个性化通道;

长链接推送通道

系统架构:

20170206004.png

模块简介:

  • Dispatcher:长链接分发层,负责推送消息分发,组播推送通知;
  • TTGateway:长链接接入层,负责长链接接入,消息下发,实时回执;
  • CallbackService:推送回执服务,包含长链接地址获取接口;
  • SLB:阿里云弹性负载均衡,数据指标:单实例500w连接;
  • RDS:阿里云Redis服务,数据指标:单集群20w连接,60w QPS;

流程简介:

  • 服务端流程:LogicCenter打包推送数据,通过阿里云负载均衡(SLB),发送http请求: push_msg 发送道Dispatcher模块,Dispatcher模块解析消息,将消息写入用户离线消息队列,向所有的TTGateway模块通过rpc调用组播推送通知,TTGateway接收组播通知,检测是否有对应长链接在线,如果在线,进行请求RDS继续消息下方,收到APP应答包后,调用回执服务 http://callback ,提交用户到达数据信息。
  • 客户端流程:APP通过配置接口获取是否开启长链接通道,如果开启,请求获取接入层地址,选择一个地址进行TCP连接、握手、注册等,定期心跳,接收下发推送消息;

APNS Provider

模块简介:

20170206005.png

对于苹果APNS推送,我们实现了一套APNS provider服务,和苹果APNS服务进行交互,对外提供带有鉴权信息的HTTP服务,分别支持两个版本的APNS协议:TCP、HTTP2,HTTP2版本的APNS协议对原有的TCP二进制协的弊端进行了大量优化,解决了二进制协链接维护、吞吐率等问题,新老协议主要差异如下图:左图-TCP协议,右图-HTTP2协议

20170206006.png

头条有效期推送周期内有几亿可推送设备,因用户卸载,token过期等因素会导致很多无效token,因此采用老的TCP协议会经常性的断链接,重连,因APNS服务部署在美国,跨洋建立链接成本消耗非常大,加上国际出口经常性的网络抖动对于链接稳定性也产生了极大影响,对于推送服务的整体吞吐率影响很大,HTTP2协议版本针对这一点进行了极大优化。 另外,针对国际出口抖动,我们做了一套三网运营商代理自动切换模块,超过一定阈值内的网络抖动会自动切换到其他运营商出口,确保服务稳定可靠,稳定性可以99.99%;

20170206007.png

上图为apns provider 简要架构图,对外提供Http服务,支持多APP单播、组播推,通过内存队列全异步实现消息推送,对于APNS协议,开发了一套针对APNS协议的http2连接池,支持动态调节连状态和出口运营商网络,支持实时消息回执和无效token清理。

推送数据体系:

内容简介:

20170206008.png

数据建模

作为平台级的产品,我们要针对核心数据流做到足够的抽象、通用、可扩展,因此,推送系统数据体系首先对数据进行抽象定义,真对目前的现状和未来发展场景来看,主要几个核心关键点:

  • 消息ID:消息,定义为一次推送调用(单播、组播、广播),消息ID,唯一标识,用于统计和追查,贯穿整个数据流,需要开发一套消息生成器模块。
  • 任务ID:任务,定义为一批推送的聚合,类似目前的rule_id, 但是目前的rule 仅限于文章推送,扩展新差,因此,我们要提供一个任务聚合的机制,任务ID,唯一标识,需要开发一套任务分配与聚会模块,可以指定任务,也可以由系统分配任务,用于效果计算、实时统计等。
  • 发送历史:目前的发送信息,扩展性较差,因此重新定义为:基础设备信息+消息信息 + 任务信息 + Extra(透传、添加),其中Extra字段可以透传用户自定义信息,也可以由推送系统添加一些必要信息。

数据收集

  • 核心数据流,包括目前的发送日志、频控日志、到达日志、动作日志,这里的动作日志扩展为推送点击、推送开关、推送收藏、推送Dislike等,主要来自回执服务和客户端上报APP日志;
  • 业务逻辑数据,主要包括推送设备和推送通道数据,由于效果统计和监控等;

数据计算

  • 数据聚合,作为效果统计的计算依赖,需要把所有核心数据流跟进消息id和任务id聚会在一起,形成完成的可以贯穿推送的系统的日志数据;
  • 实时计算,主要应用于推送效果,数据趋势;
  • 数据监控,包括成功率、失败率、数据量等监控;
  • 离线计算,主要应用于统计报表、设备计算,设备计算主要应用于个性化通道;

数据存储

  • 数据存储两大原则:全数据、可追溯,对于原始数据要持久化hdfs中,导致hive和hbase用于查询,对于效果数据,存储Mysql和redis,用于数据展示;

数据展示

  • 推送系统数据体系最终要通过数据平台进行对外提供服务,包括:用户推送历史、实时效果数据、数据趋势数据、统计报表数据、监控报警数据等;

客户端设计:

SDK发展历程

推送SDK的发展大致分为4个阶段:Pull阶段;单通道阶段;多通道阶段;模块化阶段

  • Pull阶段:在头条发布后的第1年中,头条的消息都是定时从后端拉取的。这个阶段考虑最多的是建立消息的机制,对于设备到达率低和消息到达不及时的问题考虑不多
  • 单通道阶段:在头条发展的第2年,头条Android这边开发了自己的长连接通道。这个阶段考虑最多的是消息的及时到达,也还没有考虑设备到达率低的问题
  • 多通道阶段:在头条发展的第2年底和第3年初,头条Android这边依次引入了小米,友盟等第三方通道,形成了当前多通道SDK的基础。这个阶段开始着重考虑设备到达率低的问题
  • 模块化阶段:在头条发展的第3年底和第4年,随着头条的发展,由于推送SDK包含了大量的方法数,会造成Android客户端的方法数超限(单dex65536个方法限制);多个App接入推送功能需要代码合并,接入困难且易出错等。为了解决这些工程问题,我们引入了模块化的概念,形成当前的推送SDK。这个阶段我们开始把推送作为一个公司级基础业务来看,重点解决大型App及多个App接入推送SDK的问题

SDK的架构进化

推送SDK的架构的进化分为3个阶段: 单进程阶段;双进程阶段;多进程阶段

  • 单进程阶段包含了pull阶段和单通道阶段,架构图如下:

20170206009.png

从架构图上可以看出这个阶段的消息轮询逻辑和消息展示处理逻辑都在主进程,结构比较简单。

NotifyService模块用来处理消息轮询逻辑:

  1. 通过设置闹钟来定时请求后端推送消息API接口,请求时间间隔有个初始值,之后每次API请求都会带回下一次请求的时间间隔,客户端根据返回的时间间隔来做下一次闹钟唤起的设置;
  2. 前台界面的生命周期处理,每次前台界面的显示和隐藏都会回传给NotifyService, NotifyService根据前台界面的状态对闹钟做一些策略的调整,避免对用户的正常使用造成干扰;
  3. NotifyService收到消息后,把消息进行解析(中间会有解密处理)并分发给MessageShowHandler模块。

MessageShowHandler模块是用来处理消息的展示逻辑:

  1. 对消息进行虑重(如用户已经看过的内容不再展示);
  2. 把消息解析成内部可以处理的格式,分系统通知(应用在后台)和内部弹窗(应用在前台)展示给用户。

单通道阶段只是在pull机制的基础上增加了一个自有长连接消息通道机制,具体内容参见下文自有推送通道

  • 双进程阶段是为了解决单通道阶段设备到达率低的问题,架构图如下:

20170206010.png

从架构图上可以看出,这个阶段增加了一个push进程,把单进程阶段的消息接收和处理逻辑放到了push进程中去,而原有的消息展示逻辑还在主进程,另外增加了一个MessageApp_ _Manager用来管理主进程和push进程之间的通信。这个阶段可以把push进程看做是push服务,技术上主要解决的问题是主进程和push进程之间的通信问题:

  1. 通过Android提供的跨进程通信机制Binder来处理跨进程回调类的通信;
  2. 通过Android跨进程共享进制ContentProvoder来处理配置类参数的通信
  • 多进程阶段主要是为了解决自有推送通道的缺陷(如MIUI会限制后台进程的长期存在),引进MIUI的系统push通道机制和友盟的App联盟唤醒机制,这个阶段的架构图如下:

20170206011.png

从架构图上可以看出,这个阶段增加了一个pushservice的进程,之所以没把第三方通道放到push进程就是为了避免第三方通道对自有push通道的干扰(第三方push一般认为是不太可靠的,会引起无法控制的crash问题)。增加第三方push,需要解决的技术问题是抽象第三方push的对外接口以便于进行统一管理。根据头条业务需要,第三方push被抽象成了三个接口:register, unregister, bind alias (绑定自有device_id和第三方push 通道id, 以方便push后端根据统一的device_id来推送消息)

自有推送通道

自有推送通道的详细架构图如下:

20170206012.png

  • 通道的建立和管理
  1. 通道建立过程(PushConnection)实际上就是客户端通过socket和服务器建立一个长连接通道,通过write和read数据包来完成和服务端的通信:通过Java SocketChannel来建立异步通信通道;使用Java selector机制来监听通道的建立,读,写事件; 读写过程使用Java NIO buffer API 来读写二进制流; 业务消息的编解码使用MesssagePack来处理
  2. 通道的管理(PushAppManager)主要涉及通道的建立,握手,App注册,心跳, 消息分发,关闭等

转载自http://techblog.toutiao.com/archives/2017/01/push/
侵删联系hi[#]imteek.com

如何关闭 Mac 开机声?

最近每次开机都发现【咚】的声音,而且超大声那种。后来发现,原来是我一直插着耳机的原因,系统的声音开满了。

尝试拔掉耳机,调至静音,果然就没了。

  • 拔掉耳机,音响等插头
  • 注销
  • 在登录界面调整音量大小