nsq的源码比较简单,值得一读,特别是golang开发人员,下面重点介绍nsqd,nsqd是nsq的核心,其他的都是辅助工具,看完这篇文章希望你能对消息队列的原理和实现有一定的了解。
nsqd是一个守护进程,负责接收,排队,投递消息给客户端,并不保证消息的严格顺序,nsqd默认监听一个tcp端口 (4150) 和一个http端口 (4151) 以及一个可选的https端口
对订阅了同一个topic的同一个channel的消费者使用负载均衡策略,其实就是多个协程消费同一个channel
只要channel存在,即使没有该channel的消费者,也会将生产者的message缓存到队列(内存队列和磁盘队列)中,当有新的消费者产生后,就开始消费队列中的所有消息
保证队列中的 message 至少会被消费一次(在进程意外退出的时候这点都保证不了),并不能保证成功消费一次,即使 nsqd退出,也会将队列中的消息暂存磁盘上(进程退出的时候会将缓存中的消息存到磁盘上,意外情况如掉电就不行了,缓存中的消息就没有机会存盘而丢失,在实战中一般不会使用缓存队列即内存buffer为0,全部使用磁盘队列)
限定内存占用,能够配置nsqd中每个channel队列在内存中缓存的message数量,一旦channel的buffer写满,就将message写到磁盘中,这点使用golang select的优先级功能,default优先级最低
topic,channel 一旦建立,将会一直存在,要及时在管理台或者用代码清除无效的 topic 和 channel,避免资源的浪费,每个topic和channel都有独立的协程处理自身的消息,默认的buffer和其他的一些信息
nsq消息没有备份,一旦出现进程意外情况退出,可能会出现消息丢失,如没有消费成功的消息,写入文件但没有真正落盘的消息,这种意外情况很难杜绝,像意外退出这种情况kafka,redis等都会遇到这样的问题,最后都会采用一个折中的策略,定时将数据落盘
//原文:https://www.cnblogs.com/hlxs/p/11445103.html 作者:啊汉
type Topic struct {
// 64bit atomic vars need to be first for proper alignment on 32bit platforms
messageCount uint64 //消息总数量
messageBytes uint64 //消息总长度
sync.RWMutex
name string //topic name
channelMap map[string]*Channel //保存topic下面的所有channel
backend BackendQueue //磁盘队列
memoryMsgChan chan *Message //内存队列
startChan chan int
exitChan chan int
channelUpdateChan chan int
waitGroup util.WaitGroupWrapper
exitFlag int32 //退出标记
idFactory *guidFactory //生成msg id的工厂
ephemeral bool //是否临时topic
deleteCallback func(*Topic) //删除topic方法指针
deleter sync.Once
paused int32 //暂停标记,1暂停, 0正常
pauseChan chan int
ctx *context
}
Topic创建
nsqd用map[string]*Topic来保存所有topic,producter在发消息的时候回指定topic,nsqd在收到消息后会判断topic是否存在,不存在就会自动创建,每创建一个新的topic就会启动一个协程,用于处理topic相关的消息,如将内存/磁盘中的消息复制给topic中的每个channel、channel数量变化、channel暂停、topic退出
消息结构
// Command represents a command from a client to an NSQ daemon
//原文:https://www.cnblogs.com/hlxs/p/11445103.html 作者:啊汉
type Command struct {
Name []byte //命令名称,可选:IDENTIFY、FIN、RDY、REQ、PUB、MPUB、DPUB、NOP、TOUCH、SUB、CLS、AUTH
Params [][]byte //不同的命令做不同解析,涉及到topic的,Params[0]为topic name
Body []byte //消息内容
}
// WriteTo implements the WriterTo interface and
// serializes the Command to the supplied Writer.
//
// It is suggested that the target Writer is buffered
// to avoid performing many system calls.
func (c *Command) WriteTo(w io.Writer) (int64, error) {
var total int64
var buf []byte
n, err := w.Write(c.Name) //命名名称,nsqd根据这个名称执行相关功能
total += int64(n)
if err != nil {
return total, err
}
for _, param := range c.Params {
n, err := w.Write(byteSpace) //空格
total += int64(n)
if err != nil {
return total, err
}
n, err = w.Write(param) //参数
total += int64(n)
if err != nil {
return total, err
}
}
n, err = w.Write(byteNewLine) //空行\n
total += int64(n)
if err != nil {
return total, err
}
//消息内容
if c.Body != nil {
bufs := buf[:]
binary.BigEndian.PutUint32(bufs, uint32(len(c.Body)))
n, err := w.Write(bufs) //消息长度4字节
total += int64(n)
if err != nil {
return total, err
}
n, err = w.Write(c.Body) //消息内容
total += int64(n)
if err != nil {
return total, err
}
}
return total, nil
}
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS0AAADJCAYAAAB2QWTOAAAEz3RFWHRteGZpbGUAJTNDbXhmaWxlJTIwbW9kaWZpZWQlM0QlMjIyMDE5LTA4LTIwVDA0JTNBNTklM0EzMC4wNjNaJTIyJTIwaG9zdCUzRCUyMnd3dy5kcmF3LmlvJTIyJTIwYWdlbnQlM0QlMjJNb3ppbGxhJTJGNS4wJTIwKE1hY2ludG9zaCUzQiUyMEludGVsJTIwTWFjJTIwT1MlMjBYJTIwMTBfMTRfNiklMjBBcHBsZVdlYktpdCUyRjUzNy4zNiUyMChLSFRNTCUyQyUyMGxpa2UlMjBHZWNrbyklMjBDaHJvbWUlMkY3Ni4wLjM4MDkuMTAwJTIwU2FmYXJpJTJGNTM3LjM2JTIyJTIwZXRhZyUzRCUyMjZRUFByTWJtU1pzLXlGckZtQ2puJTIyJTIwdmVyc2lvbiUzRCUyMjExLjEuNSUyMiUyMHR5cGUlM0QlMjJkZXZpY2UlMjIlMjBwYWdlcyUzRCUyMjElMjIlM0UlM0NkaWFncmFtJTIwaWQlM0QlMjJiN2ZsbFRiaW1fckIzNzJyZm1UMCUyMiUyMG5hbWUlM0QlMjJQYWdlLTElMjIlM0V6WlpiazVNd0ZNYyUyRnpabFpIJTJCeHd2endTTHF2cnVEcDJIQzl2RVZMQUFjTFExRkklMkZ2U2NRYUd1N2EzVjA3UXVjJTJGSE9TayUyRnp5RHdPWVlkM2ZkclF0WHZPTVZXQm9XUTltQklhaFc0YURMNm5zUnNWMXpWSEl1ekpUU1h0aFdYNW5TdFNVdWlrenRqNUtGSnhYb215UHhaUTNEVXZGa1VhN2ptJTJCUDAxYThPcTdhMHB5ZENNdVVWcWZxaHpJVHhhaDZocnZYWDdBeUw2Ykt1dU9QUFRXZGt0Vk8xZ1hOJTJCUFpBTW1Nd3c0NXpNVVoxSDdKS3dwdTRqT09TQjNybmhYV3NFWmNNY0VrY05XOVdYNlAwOXVPciUyRnU3em1oUjN6OVVzMzJpMVVSdUcyQVpmQnhKQmJBRWhFRmlEb29HSGlndUJDd1RyT0JYV0pGODZqSElaM1NRdjc3SDB1JTJCZ1RQdCUyQiUyQko0dkY0cG5hdHRoTkxEdSUyQmFUSW1sNlBoa0cxUkNyWnNhU3A3dCUyQmdlMUFw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" alt="" name="en-media:image/png:7a17e032d160821ded332e8e14147a44:none:none" width="301" />
nsqd收到这个结构做解析,就能知道命令名称(干什么),topic name,消息内容等,不同的命令,命令参数不一样
func (p *protocolV2) Exec(client *clientV2, params [][]byte) ([]byte, error) {
if bytes.Equal(params[], []byte("IDENTIFY")) {
return p.IDENTIFY(client, params)
}
err := enforceTLSPolicy(client, p, params[])
if err != nil {
return nil, err
}
switch {
case bytes.Equal(params[], []byte("FIN")):
return p.FIN(client, params)
case bytes.Equal(params[], []byte("RDY")):
return p.RDY(client, params)
case bytes.Equal(params[], []byte("REQ")):
return p.REQ(client, params)
case bytes.Equal(params[], []byte("PUB")):
return p.PUB(client, params)
case bytes.Equal(params[], []byte("MPUB")):
return p.MPUB(client, params)
case bytes.Equal(params[], []byte("DPUB")):
return p.DPUB(client, params)
case bytes.Equal(params[], []byte("NOP")):
return p.NOP(client, params)
case bytes.Equal(params[], []byte("TOUCH")):
return p.TOUCH(client, params)
case bytes.Equal(params[], []byte("SUB")):
return p.SUB(client, params)
case bytes.Equal(params[], []byte("CLS")):
return p.CLS(client, params)
case bytes.Equal(params[], []byte("AUTH")):
return p.AUTH(client, params)
}
return nil, protocol.NewFatalClientErr(nil, "E_INVALID", fmt.Sprintf("invalid command %s", params[]))
}
Topic收到消息
nsqd收到上面这个结构,解析之后,就会执行相关功能,我们以PUB命令为例:
1:读到空行处,能拿到命令名称和参数,命令名称=PUB,命令参数为topicName
2:检查topicName是否有效
3:获取消息内容长度,读取4个字节
4:分配对应内容长度空间,读取对应长度字节存入
5:获取topicName信息,没有就创建
6:构造消息结构体nsqd.Message,自动生成消息id
7:将消息提交给对应的topic,Topic.PutMessage
8:将消息写入topic对应的内存消息通道,内存消息通道默认大小为10000,如通道满了则写入磁盘
Topic中的消息分发给channel
在创建topic的时候回启动一个协程处理各种消息,其中就包括消费topic中的消息,topic只是将消息投递到其中的每个channel中,如topic下面有10个channel,则要复制9个nsqd.Message,每个channel一个nsqd.Message,但是消息id和消息内容是一样的,消息内容并不会被复制,topic收到消息将消息分发给channel就完事了,消息怎么发给消费者,由channel负责
type Channel struct {
// 64bit atomic vars need to be first for proper alignment on 32bit platforms
requeueCount uint64 //重新入队数量
messageCount uint64 //消息数量
timeoutCount uint64 //超时数量,已经消费,但没有反馈结果,会重新加入队列,messageCount不会自增
sync.RWMutex
topicName string //topic name
name string //channel name
ctx *context
backend BackendQueue //将消息写入磁盘的队列,维护磁盘消息的读写
memoryMsgChan chan *Message //内存消息队列,通道buffer默认10000
exitFlag int32 //退出标记,1表示退出,0没有退出
exitMutex sync.RWMutex
// state tracking
clients map[int64]Consumer //连接到这个topic-channel的所有client
paused int32 //暂停标记,0不暂停,1暂停,暂停就不会往这个channel中copy消息
ephemeral bool //临时channel标记,临时channel不会存到文件中
deleteCallback func(*Channel) //用于从topic中删除channel
deleter sync.Once
// Stats tracking
e2eProcessingLatencyStream *quantile.Quantile
// TODO: these can be DRYd up
deferredMessages map[MessageID]*pqueue.Item //延迟消息map,方便查找
deferredPQ pqueue.PriorityQueue //延迟消息队列
deferredMutex sync.Mutex
inFlightMessages map[MessageID]*Message //消费中的消息map,方便查找
inFlightPQ inFlightPqueue //消费中的消息队列
inFlightMutex sync.Mutex
}
client订阅topic消息
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAX0AAABlCAYAAAChizMTAAAEaXRFWHRteGZpbGUAJTNDbXhmaWxlJTIwbW9kaWZpZWQlM0QlMjIyMDE5LTA4LTIwVDA4JTNBMTElM0EwOS44NjlaJTIyJTIwaG9zdCUzRCUyMnd3dy5kcmF3LmlvJTIyJTIwYWdlbnQlM0QlMjJNb3ppbGxhJTJGNS4wJTIwKE1hY2ludG9zaCUzQiUyMEludGVsJTIwTWFjJTIwT1MlMjBYJTIwMTBfMTRfNiklMjBBcHBsZVdlYktpdCUyRjUzNy4zNiUyMChLSFRNTCUyQyUyMGxpa2UlMjBHZWNrbyklMjBDaHJvbWUlMkY3Ni4wLjM4MDkuMTAwJTIwU2FmYXJpJTJGNTM3LjM2JTIyJTIwZXRhZyUzRCUyMlNSd2NNOEs5X0FMTnllcDdLNUgtJTIyJTIwdmVyc2lvbiUzRCUyMjExLjEuNSUyMiUyMHR5cGUlM0QlMjJkZXZpY2UlMjIlMjBwYWdlcyUzRCUyMjElMjIlM0UlM0NkaWFncmFtJTIwaWQlM0QlMjJiN2ZsbFRiaW1fckIzNzJyZm1UMCUyMiUyMG5hbWUlM0QlMjJQYWdlLTElMjIlM0V4WlpkYjVzd0ZJWiUyRnpaRzZpMG5ZRUNDWG1OQk9yYlpkUk5PbTNYbmdnQ2VEa2VNTXNsOCUyRlUwd0lvaCUyQjA2cHFyMkk4UEhQejRqUURjdUd4dkZLMkx6ekpqQXJDVHRlQnVBR1BrWWQlMkY4ZE9UWWt5QndlNUFybnRtaUVXejVYMmFoWSUyQm1CWjJ3JTJGS2RSU0NzM3JLVXhsVmJGVVR4aFZTamJUc3AwVTA2NDF6ZGtNYkZNcTV2UTd6M1RSMHhBSEklMkYlMkZFZUY0TW5aRyUyRjdsZEtPaFRibmV3TG1zbm1ETGtKdUxHU1V2ZWpzbzJaNk9RTlh2cnJyaDlaUFQyWVlwVmVja0ZBa2szMWRmZDdrOTc4dUd0dmYlMkI1SmNmdlIzdVVQRlFlN1lVaFdzRVpBTnBCNFFBaEUzajF4SURRa2dDZ0FZdnI0d3ZRa3Y1UVo1ZDFvJTJCNDNZWGVyam9FN0pRNVd4cnJ0aktwcUNhN2F0YWRxdE5pWXNoaFc2RkdhR3pOQSUyQkIxT2F0WTl1RUoyMG1id3hX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" alt="" name="en-media:image/png:cfb2a7adcf14e1145b8d94a27606916a:none:none" />
订阅发送的还是Command这个结构,只不过订阅没有消息内容而已,指定topic和channel就行,如果topic和channel不存在都会自动创建,client和server建立的是tcp长连接,server会启动两个协程,一个用于发消息,一个用于接收消息,建立连接后,channel会把client加入它的map[int64]Consumer中,key为clientId,当topic收到消息后,会分发给channel,channel通过发消息的协程发给client
channel将消息推给消费者
channel中的消息存在两个地方:内存通道和磁盘队列,topic将消息分发给channel时,通过go的select将消息分发给内存通道或是磁盘队列,由于select的default分支优先级比case低,所以只要内存通道没满,就会往内存通道中写,否则就写入磁盘,
diskqueue.diskQueue维护着磁盘数据的读写,每个非临时的topic和channel都有这样一个字段。
发消息的协程就会一直读内存通道和磁盘队列中的数据,将消息发给client
aaarticlea/png;base64,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Txsvypulr9n9a3V9ii34KRLBluAXjJtqBX6KRLAl+AXjplqBnyIRbAl+wbipVuCnSARbgl8wbqoV+CkSwZbgF4ybagV+ikSwJfgF46ZagZ8iEWwJfsG4qVbgp0gEW4JfMG6q1VjmBw9s9SnAEgRAAARAAARAAARAAARAAARAAARAAARAAARAAARAoKUIwIDdUpcDnQEBEAABEAABEAABEAABEAABEAABEAABEAABEAABEFAEYMBWJLAEARAAARAAARAAARAAARAAARAAARAAARAAARAAARBoKQIwYLfU5UBnQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEFAEYsBUJLEEABEAABEAABEAABEAABEAABEAABEAABEAABEAABFqKAAzYLXU50BkQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAFFAAZsRQJLEAABEAABEAABEAABEAABEAABEAABEAABEAABEACBliIAA3ZLXQ50BgRAAARAAARAAARAAARAAARAAARAAARAAARAAARAQBGAAVuRwBIEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQKClCMCA3VKXA50BARAAARAAARAAARAAARAAARAAARAAARAAARAAARBQBGDAViSwBAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQaCkCMGC31OVAZ0AABEAABEAABEAABEAABEAABEAABEAABEAABEAABBQBGLAVCSxBAARAAARAAARAAARAAARAAARAAARAAARAAARAAARaigAM2C11OdAZEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABRQAGbEUCSxAAARAAARAAARAAARAAARAAARAAARAAARAAARAAgZYiAAN2S10OdAYEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQEARgAFbkcASBEAABEAABEAABEAABEAABEAABEAABEAABEAABECgpQhEMpmM7w4FaVPrINBXi079feBXn1GtGuBXi079feBXn1GtGuBXi079feBXn1GtGuBXi079feBXn1GtGuBXi079feBXn1GtGuBXi079feBXn1GtGuBXi079feBXn1GtGuBXi079feBXn1GtGuBXi079fWOZHzyw638+UAMEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQGAUCERisZjnwypLv582XpQ3S1+z+9fq+hRb8FMkgi3BLxg31Qr8FIlgS/ALxk21Aj9FItgS/IJxU63AT5EItgS/YNxUK/BTJIItwS8YN9UK/BSJYEvwC8ZNtQI/RSLYEvyCcVOtwE+RCLYEv2DcVKuxzA8e2OpTgCUIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgEBLEYABu6UuBzoDAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiCgCMCArUhgCQIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIg0FIEYMBuqcuBzoAACIAACIAACIAACIAACIAACIAACIAACIAACIAACCgCMGArEliCAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAi0FAEYsFvqcqAzIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACigAM2IoEliAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAi1FAAbslroc6AwIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgIAiAAO2IoElCIAACIAACIAACIAACIAACIAACIAACIAACIAACIBASxGAAbulLgc6AwIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgoAjAgK1IYAkCIAACIAACIAACIAACIAACIAACIAACIAACIAACINBSBGDAbqnLgc6AAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAgoAjBgKxJYggAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAItBQBGLBb6nKgMyAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAooADNiKBJYgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAItRQAG7Ja6HOgMCIAACIAACIAACIAACIAACIAACIAACIAACIAACICAIgADtiKBJQiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAQEsRgAG7pS4HOgMCIAACIAACIAACIAACIAACIAACIAACIAACIAACIKAIRKZPn67Ko7KcMmXKqBwXBwUBEAABEAABEAABEAABEAABEAABEAABEAABEAABEGgOgQ8//LA5iiq0GBZLxbaqq5lMxt4Xi8Wq1vG7wzAMv01QHwRAAARAAARAAARAAARAAARAAARAAARAAARAAARAoIUI+DAzV+21m/05UrX2CO9oxgmOcJdxOBBoOwJqwAjft7a7dOgwCBC+v/gQgED7EsD3t32vHXoOAvj+4jMAAu1LAN/f9r126Hn7EVDft+HqOWJgDxdZ6AUBEAABEAABEAABEAABEAABEAABEAABEAABEAABEGiIAAzYDeFDYxAAARAAARAAARAAARAAARAAARAAARAAARAAARAAgeEiAAP2cJGFXhAAARAAARAAARAAARAAARAAARAAARAAARAAARAAgYYIwIDdED40BgEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQGC4CMGAPF1noBQEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQaIgADNgN4UNjEAABEAABEAABEAABEAABEAABEAABEAABEAABEACB4SIAA/ZwkYVeEAABEAABEAABEAABEAABEAABEAABEAABEAABEACBhgjAgN0QPjQGARAAARAAARAAARAAARAAARAAARAAARAAARAAARAYLgIwYA8XWegFARAAARAAARAAARAAARAAARAAARAAARAAARAAARBoiAAM2A3hQ2MQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAIHhIgAD9nCRhV4QAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAIGGCMCA3RA+NAYBEAABEAABEAABEAABEAABEAABEAABEAABEAABEBguAjBgDxdZ6AUBEAABEAABEAABEAABEAABEAABEAABEAABEAABEGiIAAzYDeFDYxAAARAAARAAARAAARAAARAAARAAARAAARAAARAAgeEiAAP2cJGFXhAAARAAARAAARAAARAAARAAARAAARAAARAAARAAgYYIwIDdED40BgEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQGC4CkUwm41t3kDa+D4IGIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACbUGgmTZjXRc8sNvi8qOTIAACIAACIAACIAACIAACIAACIAACIAACIAACIDD2CERisZjns1aWbz9tPCtHRRAAARAAARAAARAAARAAARAAARAAARAAARAAARAAgbYk0AybsZv9GR7YbflxQKdBAARAAARAAARAAARAAARAAARAAARAAARAAARAoPMJwIDd+dcYZwgCIAACIAACIAACIAACIAACIAACIAACIAACIAACbUkABuy2vGzoNAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAh0PgEYsDv/GuMMQQAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQKAtCcCA3ZaXDZ0GARAAARAAARAAARAAARAAARAAARAAARAAARAAgc4nAAN2519jnCEIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAItCUBGLDb8rKh0yAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiDQ+QRgwO78a4wzBAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAIG2JAADdlteNnQaBEAABEAABEAABEAABEAABEAABEAABEAABEAABDqfAAzYnX+NcYYgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIg0JYEYMBuy8uGToMACIAACIAACIAACIAACIAACIAACIAACIAACPx/e+cCb09V1fGh/v41NCWDNEoemQ9KisosjESzSOOhlEWUISJmqRUkPVRMM0yNXoTgI0UgDUwgRTOjFCQzIQoKyMzsD5qYZRmlaZid1nfLmv86++55nXPuvefM+a3P596ZM7Nnz8x3Zs/ee+211haB8ROQAnv8z1h3KAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIrSUAK7JV8bLpoERABERABERABERABERABERABERABERABERABERg/ASmwx/+MdYciIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIisJIEpMBeycemixYBERABERABERABERABERABERABERABERABERCB8ROQAnv8z1h3KAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIrSUAK7JV8bLpoERABERABERABERABERABERABERABERABERABERg/gR133HHH4Luc5ZjBJ9EBIiACIiACIiACIiACIiACIiACIiACIiACIiACIiACK0FgkTrjmJcssFfi8esiRUAEREAEREAEREAEREAEREAEREAEREAEREAERGD9COzYuXNn77t2zfeQY3pnroQiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIrSWAROuOS/lkW2Cv5OuiiRUAEREAEREAEREAEREAEREAEREAEREAEREAERGD8BKTAHv8z1h2KgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIwEoSkAJ7JR+bLloEREAEREAEREAEREAEREAEREAEREAEREAEREAExk9ACuzxP+Mtu8PPfe5zFX8SERCB5SSgMrqcz0VXNX4Cn/rUp6rJZDL+G9UdioAIiIAIiMAKE1BbeYUfni59Wwmo7Gwr/rU5uRTYS/aoP/axj1X/8R//MddVvfSlL60e//jHp79rr712rryGHPwrv/Ir1Y4dO6oHPehB1U//9E8POXSutOecc071lKc8pTr55JOr2267bea8/u///q9617veNfPxfQ/kWh/2sIdVe+yxR/XGN76x72FKtyQEVEaHPYgPfvCD1Uc+8pHGgy6++OL0zeC7cfbZZzeme+9731tdc8011Wc/+9nGNNu142//9m+rSy65JP198pOf3K7L0Hk3icB5551XveAFL6he+MIXVrfffvugs1x33XXVD//wD1f3uMc9qt/+7d8edOyyJn75y19eHXHEEelvK9sYy8pD17UYArTBPv7xj1c333xz9c53vrO66KKLql//9V+vnv/851fs6yvUFbt27eqbvDHd9ddfX93znvdMfyeccEIy0HjVq16V6qu/+Iu/aDxunh203b/pm76p4nzve9/75smqeOxnPvOZ6n//93+n9v3ET/xEddhhh6W/T3/60/U+0lJ/l+S4446rHv3oR6e2/kc/+tFSEm1bcwJqK6/5C6Dbn5mAys7M6BoP9Lr8/ve/fxXrucYDNmnHH/7hHyb93P3ud79U527SaUaf7Y7R3+EK3SAd3e/4ju+o9tlnn+pNb3pTdfDBB2+4epTbr3jFK1Lh+8Vf/MUN+9lw5ZVXVn/0R3+U9qHULck//MM/VN/2bd9WnXrqqdXTnva06ku+5EtKyXpvo3Nx7rnnpvR///d/Xz31qU/tfey8CbnfSy+9NGXzAz/wA9W+++47OEsa9D/2Yz9WveY1r6l++Zd/uXr2s589OI++B6C49s7PWWedVX3/939/30OVbpsJqIz2fwAf/vCHq+/7vu9L7/oDH/jApJRggCuXv/u7v6v4ZiD/9m//lu9Ov//7v/87Kcv+67/+K/1GyfGlX/qlxbRxIwoAn704bh+yfsABB1T3ute9Wg9585vfXD3nOc9JaX7nd36neuITn9iaXjtXiwDP9KqrrkoX/ahHPar69m//9t43gPL7d3/3d1N66trv+q7vqg488MCp46k/c6XSVIIeP77gC74gDSDnSV//+tdXN954Y765/k1jnrbAhRdeWG/LV771W781Nbh9O0qtP/7jP04/f+qnfiot//M//zO1Tb73e7+3+uqv/mpPquWaEOA7S6fQ/1B+8t3mm80f70f8+/d///f0vf/Xf/3X6l/+5V8q6gv/vpeQfed3fmevcseA6PHHH1998Rd/cfWOd7yj+uZv/uZSdr224THh18S10y6nDCNHHXVURXuATmiTYFDBdfDXRzgfinvO+Vd/9VfVaaed1uewXml4Hj/+4z+e2sqwvOyyy+rjbrrppurP/uzP0u84UPDKV76yOuWUU6rHPe5x1atf/epq7733ro/he8hz43p/8id/st6uFRGAgNrKeg9EYDYCKjuzcWs7ivrP63KW6GG2S+hP0mdE/umf/qlioPwbvuEbtutyVva8G7UJK3srq33h//zP/1w3tClcX/d1X5esT37wB3+wvjEK4H777VcXQqx4jzzyyHr/kBWULTQ+UdSiFH/JS17Sejidk1tvvbUxzV/+5V+mgugJHv7wh1cf+MAH/GfrklGx+9znPq1pNnMnFp0nnnhirWSAzSGHHFI99rGP7Twtjf3Y4O88wBL8/M//fFKUk5ZOA+y+/uu/vs+hKQ2KCv4kW0tAZXRYGf3yL//y6n/+53/SQ0JBjSLvR3/0R2d6aOeff3793WOgqY/ymhNhzebK8ZlObAf91m/9VoWFGuX8937v91I2DDJifSZZDgIoivqEr6Ku6RqMWPQd4ZmEIs3fw5NOOin9jt/wP/iDP6iOOeaYuU79cz/3c8V6/IILLqiVzaUToFC/293uVuG51SS0QyhLLnEginLx/ve/v3rEIx6R2hQMAmMBO++guJ9Ly+UmcMUVV1Tf/d3fvekXiYdL18ARVmsorxHa0bSRL7/88uroo4+e6fq+8Au/sD6OASYGZ37kR36kYkCL9jNK7D//8z+v9txzzzodKyjuaVP/0i/9UhocglGeZuqAO3/ccsstdT3Hpgc/+MGlZDNto4zTJofL7//+71d//dd/3druJN3znve8dC7aqHe/+93r83J/3L9LmxLf02i5PgTUVh7WVl6fN0N32kVAZWdzyg51VhTqw+0S9GO0Zf70T/80XQLGI1Jgz/A0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pdSbS2CVyq/KTvO7QHhcQmIhhNM59thjmxN37CE0H2F/S0IbmUFw2vFDBL0b/VKEvukBBxyQ1mf5h2EYulfyIK9VkkWWt5L+eQ+L/dhbgb0Z4PzBrpJCbTMV2JvBWHmKgBNY5AfF8xzLsq8Ceyz3q/tYPQIqv6v3zHTFIuAEVH6dhJYisHoEVH5X75npikXACaj8OgktRWDzCXh5Mz3zppxsR5e1bzxrSQMe92tdBERABERABERABERABERABERABERABERABERABERg/QgM0TM30Snpn4fZxTflrO0iIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIisGACmsRxBqDEw3zJS15SedgTm+18hlx0iAiIwDIROOmkk9LEQ1wTEzdIREAEREAEREAEREAEREAEREAEREAEREAEtp+AJnHc/megKxCBLSPgMYl88GXLTqwTiYAIzE1A5XduhMpABLaNgMrvtqHXiUVgbgIqv3MjVAYisG0EVH63Db1OvIYEFlneFEJkDV8g3bIIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIrCoBxcBe1Sen6xYBERABERABERABERABERABERABERABERABERCBkROQAnvkD1i3JwIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAKrSkAK7FV9crpuERABERABERABERABERABERABERABERABERABERg5ASmwR/6AdXsiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIisKoEpMBe1Sen6xYBERABERABERABERABERABERABERABERABERCBkROQAnvkD1i3JwIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAKrSkAK7FV9crpuERABERABERABERABERABERABERABERABERABERg5ASmwR/6AdXsiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIisKoEpMBe1Sen6xYBERABERABERABERABERABERABERABERABERCBkROQAnvkD1i3JwIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAKrSkAK7FV9crpuERABERABERABERABERABERABERABERABERABERg5ASmwR/6AdXsiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIisKoEpMBe1Sen6xYBERABERABERABERABERABERABERABERABERCBkRPYcccddwy+xVmOGXwSHSACIiACIiACIiACIiACIiACIiACIiACIiACIiACIrASBBapM455yQJ7JR6/LlIEREAEREAEREAEREAEREAEREAEREAEREAEREAE1o/Ajp07d/a+a9d8Dzmmd+ZKKAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIisJIEFqEzLumfZYG9kq+DLloEREAEREAEREAEREAEREAEREAEREAEREAEREAExk9ACuzxP2PdoQiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAisJAEpsFfysemiRUAEREAEREAEREAEREAEREAEREAEREAEREAERGD8BKTAHv8z1h2KgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIwEoSkAJ7JR+bLloEREAEREAEREAEREAEREAEREAEREAEREAEREAExk9ACuzxP2PdoQiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAisJAEpsFfysemiRUAEREAEREAEREAEREAEREAEREAEREAEREAERGD8BKTAHv8z1h2KgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIwEoSkAJ7JR+bLloEREAEREAEREAEREAEREAEREAEREAEREAEREAExk9ACuzxP2PdoQiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAisJAEpsFfysemiRUAEREAEREAEREAEREAEREAEREAEREAEREAERGD8BKTAHv8z1h2KgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIwEoSkAJ7JR+bLloEREAEREAEREAEREAEREAEREAEREAEREAEREAExk9ACuzxP2PdoQiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAisJAEpsFfysemiRUAEREAEREAEREAEREAEREAEREAEREAEREAERGD8BKTAHv8z1h2KgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIwEoSkAJ7JR+bLloEREAEREAEREAEREAEREAEREAEREAEREAEREAExk9gxx133DH4Lmc5ZvBJdIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiMBKEFikzjjmtWNZ7n6PPfZYlkvRdYjA6AmovI3+EesGR0xA5XfED1e3NnoCKr+jf8S6wRETUPkd8cPVrY2egMrv6B+xbnANCOwxMel7n6753rlzZ99DOtPpQ9KJSAlEQAREQAREQAREQAREQAREQAREQAREQAREQAREYKkJDFAzN95HSf+87RbYt9xyS7X//vs3XvSQHaUbHHJ8nnbZ8+N6b731VvHLH9yA3+I3AFYhqfgVoAzYJH4DYBWSil8ByoBN4jcAViGp+BWgDNgkfgNgFZKKXwHKgE3iNwBWIan4FaAM2CR+A2AVkopfAcqATeI3AFYhqfgVoAzYJH4DYBWSrhO/wu1XmsSxREXbREAEREAEREAEREAEREAEREAEREAEREAEREAEREAEtp2AFNjb/gh0ASIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAiUCUmCXqGibCIiACIiACIiACIiACIiACIiACIiACIiACIiACIjAthOQAnvbH4EuQAREQAREQAREQAREQAREQAREQAREQAREQAREQAREoERACuwSFW0TAREQAREQAREQAREQAREQAREQAREQAREQAREQARHYdgJSYG/7I9AFiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIlAhIgV2iom0iIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIALbTkAK7G1/BLoAERABERABERABERABERABERABERABERABERABERCBEgEpsEtUtE0EREAEREAEREAEREAEREAEREAEREAEREAEREAERGDbCfw/Xr9D38yCBzgAAAAASUVORK5CYII=" alt="" name="en-media:image/png:bde79142da3139041a5ee7d10d073c53:none:none" />
nsq消息类型有三种如下:
// frame types
const (
FrameTypeResponse int32 = //响应
FrameTypeError int32 = //错误
FrameTypeMessage int32 = //消息
)
消息发送给client之后,也不知道消息到底有没有消费成功,有可能client收到消息之后就崩溃了,所以消息发给client之后,需要client给server发一个FIN消息告诉server,这个消息我消费成功,所以在将消息发送给client之后,消息出了内存队列/磁盘队列,进入了一个新的队列,叫飞行队列,表示这个消息正在运输消费中,为了维护在消费中的消息,nsq使用了两个数据结构:
type inFlightPqueue []*Message
inFlightPQ inFlightPqueue //按照超时时间排序的最小堆
inFlightMessages map[MessageID]*Message //保存消息
消息发送给client之后,同时会将消息存入inFlightPQ和inFlightMessages中,inFlightPQ中的消息都设置了超时时间默认是1分钟,如果1分钟后还没有收到client发过来的FIN消息,会将消息重新加入待消费队列,让client重新消费,目的是想保证每个消息至少被消费一次,由于消息可保存在内存中,进程可能随时挂掉并不能保证每个消息都至少被消费一次,如果不用内存队列,完全使用磁盘队列,当进程意外崩掉的时候,消息是否丢失要看磁盘队列的具体实现,完全使用磁盘队列性能差点,安全性更高
inFlightMessages就是为了方便通过消息id查找消息,收到client发送过来的FIN消息时就会将消息从inFlightPQ和inFlightMessages中删除,表示这个消息已经消费成功,数据也就被扔掉了
延迟消息
发延迟消息和发普通消息的区别是producter在生成延迟消息的时候指定了延迟时间,单位毫秒,命令:DPUB
延迟消息存在内存中,并没有存到磁盘中,延迟消息要是存在磁盘中,实现起来还是比较复杂
延迟消息同样使用了一个队列和一个map,结构如下:
type Item struct {
Value interface{} //*Message
Priority int64 //执行的时间戳,单位毫秒
Index int //队列索引
}
type PriorityQueue []*Item
deferredPQ pqueue.PriorityQueue
deferredMessages map[MessageID]*pqueue.Item
deferredPQ和inFlightPQ一样,是按照时间排序的最小堆
那么nsq是怎么判断消息超时,延迟消息的执行时间到了呢?
nsq有一个专门的协程来处理这两种情况,实现也很简单,就是每100毫秒检查一次,看是否有超时的消息,延迟消息是否执行时间是否到了,如果消息超时,则重新将消息加入待消费队列,每次将消息发送给client的时候,重试次数都会加一,即Message.Attempts++
延迟消息执行时间要是到了,就会当做一个普通的消息加入待消费队列,后面的流程都是一样的,默认最大延迟时间为1小时,所有的默认值在进程启动时都是可重新指定的
nsqd启动过程
1:加载启动参数
启动参数定义了结构nsqd.Options,并初始化好了默认值,在进程启动的时候可以指定对应的值,通过反射将这些参数赋给nsqd.Options,通过nsqd.Options就能方便的使用各个参数
2:加载topic和channel并启动
在nsqd启动的时候会加载配置文件nsqd.dat,验证topic和channel名称格式是否有效,然后启动所有topic,该暂停的就暂停,当topic和channel发生变更的时候回将所有信息重新保存到nsqd.dat中,如新增/删除/暂停/启动topic和channel会保存文件
topic和channel保存到文件中的结构
type meta struct {
Topics []struct {
Name string `json:"name"`
Paused bool `json:"paused"`
Channels []struct {
Name string `json:"name"`
Paused bool `json:"paused"`
} `json:"channels"`
} `json:"topics"`
}
3:启动tcp/http/https服务
nsq可以通过tcp和http通过服务,http和https提供的服务是一样,区别在于协议本身,当client通过tcp和server建立连接后,server会启动两个协程,一个用于发消息,一个用于收消息
tcp提供的服务如下:
服务命令 |
服务描述 |
INENTIFY |
认证 |
FIN |
消费完成 |
RDY |
指定可同时处理的消息数量 |
REQ |
消息重新加入队列 |
PUB |
发布单条消息 |
MPUB |
发布多条消息 |
DPUB |
发布单条延迟消息 |
NOP |
不做任何处理 |
TOUCH |
重新设置消息处理超时时间 |
SUB |
订阅,订阅后才能消费消息 |
CLS |
关闭停止消费 |
AUTH |
授权 |
client和server建立连接后,client通过命令INENTIFY将认证信息发给服务端,如果server在启动的时候指定了授权地址,server就会告诉client你需要认证,client就会通过命令AUTH将秘钥发给server,server去授权地址进行验证,验证通过后,就可以进行正常的消息发布和订阅了
http和https提供服务如下:
服务名称 |
发布单条/多条消息 |
topic新增/删除/情况topic中消息/暂停/启动 |
channel新增/删除/情况topic中消息/暂停/启动 |
nsq状态信息 |
ping |
启动参数查询和修改 |
tcp服务能发布和消费消息,http/https则只能发布消息,发布消息最后调的是同一个接口
端口信息
协议名称 |
默认端口 |
tcp |
4150 |
http |
4151 |
https |
4152 |
心跳
心跳默认30秒,在认证(INENTIFY)的时候client可以指定心跳时间间隔,server按照心跳给client发消息,消息内容:_heartbeat_,如果发送失败,发送消息的协程就会退出,这样server就不在给client发消息了,server如果从client读消息失败,接收消息的协程就会退出,关闭和client的连接,从channel中将client移除,这样就不在收client发来的消息,server中也就没有client的任何信息了
consumer和producter连着nsqd的同一个端口,为什么consumer能消费消息,而producter却不会呢?
nsq是个基于发布和订阅的消息队列,只有订阅了才能消费消息,consumer和producter虽然连着同一个端口,consumer在建立连接后,会发送SUB命令,告诉server我要订阅,而producter并没有,consumer在发送SUB命令后还会发送RDY命令告诉server能同时处理消息的个数,当rdyCount=0时,server也不会给consumer推消息,所以SUB和RDY这两个命令缺一不可
nsq消息文件的存取
nsq可以将消息存在内存中或是文件中,存在内存的好处就是速度快,确定就是一旦进程退出消息就丢失了,所以在实战中消息都会写到磁盘文件,虽然慢点但不容易丢消息
topic收到消息后,可以将消息存在内存中或是文件中,当内存channel写满之后就会写入文件,当我们把channel的buffer设置成0后,所有的消息就会写文件
每个topic都会启动一个协程将其收到的消息复制给其下面的每个channel,channel在将消息推送给consumer,channel收到topic发过来(函数调用)的消息,可将消息存入内存或是文件
消息写入内存,topic下面的channel其实是共享一份数据,因为数据都是自读的,而写入文件却是每个channel都有一组文件并将消息吸入,真正做到了读时复制,每个topic和channel都会实例化一个diskQueue,其结构如下
// diskQueue implements a filesystem backed FIFO queue
//原文:https://www.cnblogs.com/hlxs/p/11445103.html 作者:啊汉
type diskQueue struct {
// 64bit atomic vars need to be first for proper alignment on 32bit platforms
// run-time state (also persisted to disk)
readPos int64 //已经读的位置
writePos int64 //已经写的位置
readFileNum int64 //正在读的文件编号
writeFileNum int64 //正在写的文件编号
depth int64 //没有消费的消息数量
sync.RWMutex
// instantiation time metadata
name string // topicName 或者 topicName + ":" + channelName
dataPath string //存消息文件的目录
maxBytesPerFile int64 // currently this cannot change once created
minMsgSize int32 //消息最小值
maxMsgSize int32 //消息最大值
syncEvery int64 // number of writes per fsync
syncTimeout time.Duration // duration of time per fsync
exitFlag int32 //退出标记
needSync bool //强制将文件缓冲区的数据写入磁盘
// keeps track of the position where we have read
// (but not yet sent over readChan)
nextReadPos int64 //下次读的位置
nextReadFileNum int64 //下次读的文件编号
readFile *os.File //正在读的文件
writeFile *os.File //正在写的文件
reader *bufio.Reader //读缓冲区,默认4K
writeBuf bytes.Buffer //写缓冲区
// exposed via ReadChan()
readChan chan []byte //读channel
// internal channels
writeChan chan []byte //写channel
writeResponseChan chan error //写结果通知
emptyChan chan int //删除所有文件channel
emptyResponseChan chan error //删除通知channel
exitChan chan int //退出channel
exitSyncChan chan int //退出命令同步等待channel
logf AppLogFunc //写日志
}
文件名命名:目录 + topicName:channelName + .diskqueue.000001.dat
func (d *diskQueue) fileName(fileNum int64) string {
return fmt.Sprintf(path.Join(d.dataPath, "%s.diskqueue.%06d.dat"), d.name, fileNum)
}
diskQueue在实例化的时候回初始化相关的属性,当文件大小大于指定文件的最大值时,文件编号writeFileNum就会自增1,新来的消息就会写入新的文件
按顺序读写文件,每个消息写文件的格式是:消息长度(4字节) + 消息内容,这样读消息也就很容易了,先读4字节,知道消息的长度,接着读消息内容,下一个消息也是这样读,当下一个消息读的位置大于文件的最大值时说明这个文件读完了,可以从下一个文件开始写了,
写文件是同步的,写完之后直接反馈消息是否写入成功,由于文件系统的缓存原因,系统并不是把消息马上写入磁盘,而是写入了文件的缓冲区,所以需要定时的将文件缓冲区的内容写入磁盘,nsq使用了两个策略将文件缓冲区的内容写入磁盘。两个策略同时进行
1:默认每2500条消息强制将文件缓存内容写入磁盘
2:默认每两秒强制将文件缓存内容写入磁盘
在将消息强制写入磁盘的同时,也会将队列当前状态写入另一个文件,若程序退出,下次启动后就能正常进行文件的读写,写入内容包括:
1:剩余消息数量
2:正在读的文件编号
3:读文件偏移量
4:正在写的文件编号
5:写文件偏移量
磁盘文件的删除,如果一个文件中的消息全部被消费了,那这个文件将被删除
断开重连
断开后如果不能自动重连,那就是死都不知道怎么死的,所以nsq是有断开重连功能的
server短发现断开后,不会自动重连,鬼知道你是不是主动断开,所以server发现断开了,就将client的相关信息完全删除,就像client从没有出现过
client断开后会自动重连,client分consumer和producer
consumer自动重连:consumer作为消费者就是读,所以当读失败的时候,consumer会关闭读写功能,就断开连接,当consumer收到的所有消息处理完成后,就会自动重连,注意写失败并不会自动重连
producer自动重连:producer作为生产者就是写,所以当写失败的时候,producer按照状态来决定是否重连,如果发现状态为非连接状态就连接,收到断开是不会重连的,在写失败的时候才会重连
参考资料
未完。。。
- (原)NSQ源码阅读和分析(1)
原文出处:https://www.cnblogs.com/lihaiping/p/12324371.html 本文记录自己在阅读和学习nsq源码的时候的一些学习笔记,主要目的是个人总结和方便后期查阅. ...
- ABP源码分析一:整体项目结构及目录
ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
- zookeeper源码分析之五服务端(集群leader)处理请求流程
leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...
- zookeeper源码分析之四服务端(单机)处理请求流程
上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...
- zookeeper源码分析之三客户端发送请求流程
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
- java使用websocket,并且获取HttpSession,源码分析
转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...
- ABP源码分析二:ABP中配置的注册和初始化
一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...
随机推荐
- 浅谈CMDB
CMDB和运维自动化 一.运维 运维,指的是对已经搭建好的网络,软件,硬件进行维护.运维领域也是细分的,有硬件运维和软件运维 硬件运维主要包括对基础设施的运维,比如机房的设备,主机的硬盘,内存这些物理 ...
- 带新手玩转MVC——不讲道理就是干(下)
带新手玩转MVC——不讲道理就是干(下) 前言:废话不多说,直接开干 完整案例演示 案例代码 LoginServlet package servlet; import domain.User; imp ...
- python下载报错:Could not install packages due to an EnvironmentError: [WinError 5] 拒绝访问
更新pip模块的版本:python -m pip install --upgrade pip 但是遇到报错提示: Could not install packages due to an Enviro ...
- (11)ASP.NET Core 中的配置一(Configuration)
1.前言 ASP.NET Core在应用程序上引入Microsoft.Extensions.Configuration配置,可以支持多种方式配置,包括命令行配置.环境变量配置.文件配置.内存配置,自定 ...
- 2019前端面试系列——Vue面试题
Vue 双向绑定原理 mvvm 双向绑定,采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个属性的 setter.getter,在数 ...
- 【React踩坑记一】React项目中禁用浏览器双击选中文字的功能
常规项目,我们只需要给标签加一个onselectstart事件,return false就可以 例: <div onselectstart="return false;" & ...
- Office2019 VOL版本 自定义安装组件
众所周知,Office VOL版本可以连接KMS服务器激活,但是office2019没有镜像可以下载,所以只能依靠Office Deployment Tool来进行操作.注:Office2019 Re ...
- 8、JAVA中的用户输入(I/0交互过程)
这里在数组的学习中用到了用户输入,也就是交互模式,日常的数据,不可能每一次都是程序员定义好的,终究需要用户与程序之间进行交互,机器等待用户输入,用户通过键盘输入所需数据(数据包括,字符,字串,数值等) ...
- springboot整合websocket原生版
目录 HTTP缺点 HTTP websocket区别 websocket原理 使用场景 springboot整合websocket 环境准备 客户端连接 加入战队 微信公众号 主题 HTTP请求用于我 ...
- 单纯的xlistview
public class MainActivity extends AppCompatActivity implements XListView.IXListViewListener{ private ...