关于消息队列的思考

消息队列是服务架构中常见的组件,可用于服务间解耦、事件广播、任务异步/延迟处理等,本文对于消息队列的实现如何满足几种消费语义进行了阐述。

消息队列组成

  • 生产者(Producer):负责产生消息
  • 消息代理(Message Broker):负责存储/转发消息(转发分为推和拉两种,拉是指Consumer主动从Message Broker获取消息,推是指Message Broker主动将Consumer感兴趣的消息推送给Consumer)
  • 消费者(Consumer):负责消费消息


Read more...

2017-03-22 消息队列

Golang singleflight 用武之地

缓存更新问题


当缓存失效时,需要去数据存储层获取数据,然后存储到缓存中。

通常缓存更新方案:

  1. 业务代码中,根据key从缓存拿不到数据,访问存储层获取数据后更新缓存
  2. 由专门的定时脚本在缓存失效前对其进行更新
  3. 通过分布式锁,实现只有一个请求负责缓存更新,其他请求等待:一种基于哨兵的缓存访问策略

服务中某个接口请求量暴增问题


比如某个帖子突然很火,帖子下有非常多的跟帖回复,负责提供帖子内容、回帖内容的接口,对于该帖子的请求量就会非常多。

如果每个请求都落到下游服务,通常会导致下游服务瞬时负载升高。如果使用缓存,如何判断当前接口请求的内容需要缓存下来?缓存的过期、更新问题?


Read more...

2017-03-07

golang并发编程的理解

golang通过语言层面的特性goroutine和channel提供了优雅的并发编程方式,Share Memory By Communicating一文中有这么句“名言”:

Do not communicate by sharing memory; instead, share memory by communicating.

单纯看这句话其实不好理解,但结合文中的例子算是基本明白其中的含义了。

文中以编写并发拉取给定的URL资源程序为例子,展示了传统多线程并发编程模型和golang并发编程模型的不同。


Read more...

2017-02-11 GoLang并发

MySQL主从复制延迟的监控

MySQL的同步模式有三种,从官方文档可知Replication

  • With asynchronous replication, the master writes events to its binary log and slaves request them when they are ready. There is no guarantee that any event will ever reach any slave.
  • With fully synchronous replication, when a master commits a transaction, all slaves also will have committed the transaction before the master returns to the session that performed the transaction. The drawback of this is that there might be a lot of delay to complete a transaction.
  • Semisynchronous replication falls between asynchronous and fully synchronous replication. The master waits only until at least one slave has received and logged the events. It does not wait for all slaves to acknowledge receipt, and it requires only receipt, not that the events have been fully executed and committed on the slave side.

在asynchronous和Semisynchronous模式下,主库与从库之间必然存在一定延迟,当延迟大的话,从库的查询就可能查询到旧的数据,或者查询不到数据(比如主库插入的数据尚未同步到从库)。


Read more...

2016-11-06 MySQL复制

golang中的赋值

先看看文档中关于赋值的说明Assignability

A value x is assignable to a variable of type T (“x is assignable to T”) in any of these cases:

  1. x’s type is identical to T.
  2. x’s type V and T have identical underlying types and at least one of V or T is not a named type.
  3. T is an interface type and x implements T.
  4. x is a bidirectional channel value, T is a channel type, x’s type V and T have identical element types, and at least one of V or T is not a named type.
  5. x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type.
  6. x is an untyped constant representable by a value of type T.

Read more...

2016-11-05 GoLang基础

PHP 7 中函数调用的实现

先看一个函数调用的OPCode:

function foo($arg) {
    echo $arg;
}
$arg = "Hello World\n";
foo($arg);

filename:       /home/roketyyang/test.php
function name:  (null)
number of ops:  6
compiled vars:  !0 = $arg
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   NOP                                                      
   5     1        ASSIGN                                                   !0, 'Hello+World%0A'
   6     2        INIT_FCALL                                               'foo'
         3        SEND_VAR                                                 !0
         4        DO_UCALL                                                 
         5      > RETURN                                                   1

filename:       /home/roketyyang/test.php
function name:  foo
number of ops:  3
compiled vars:  !0 = $arg
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   RECV                                             !0      
   3     1        ECHO                                                     !0
   4     2      > RETURN                                                   null

第一个OPArray是/home/roketyyang/test.php文件的,第二个OPArray是foo函数的。

我们来看下/home/roketyyang/test.php是如何被Zend引擎执行的。


Read more...

2016-11-04 PHP底层

认识PHP 7虚拟机

本文内容大部分翻译自Getting into the Zend Execution engine (PHP 5),并做了一些调整,原文基于PHP 5,本文基于PHP 7。

PHP : 一门解释型语言


PHP被称为脚本语言或解释型语言。为何? PHP语言没有被直接编译为机器指令,而是编译为一种中间代码的形式,很显然它无法直接在CPU上执行。 所以PHP的执行需要在进程级虚拟机上(见Virtual machine中的Process virtual machines,下文简称虚拟机)。

PHP语言,包括其他的解释型语言,其实是一个跨平台的被设计用来执行抽象指令的程序。PHP主要用于解决WEB开发相关的问题。

诸如Java, Python, C#, Ruby, Pascal, Lua, Perl, Javascript等编程语言所编写的程序,都需要在虚拟机上执行。虚拟机可以通过JIT编译技术将一部分虚拟机指令编译为机器指令以提高性能。鸟哥已经在进行PHP加入JIT支持的开发了。


Read more...

2016-11-04 PHP底层