连接状态:
相关代码: src/net/http/server.go
状态说明:
New: 从Accept拿到一个新连接后,连接被标记为New,并触发hook
Active: 对于http2,只要连接上有请求存在,就算是Active的
Idle: 请求处理完毕,处于keep-alive状态
Hijack: 连接被偷走了,自己不需要继续处理了,这种连接不会进入Close状态的,Hijack 是个终态
Close:连接已关闭
参考:
DevOps
相关代码: src/net/http/server.go
状态说明:
New: 从Accept拿到一个新连接后,连接被标记为New,并触发hook
Active: 对于http2,只要连接上有请求存在,就算是Active的
Idle: 请求处理完毕,处于keep-alive状态
Hijack: 连接被偷走了,自己不需要继续处理了,这种连接不会进入Close状态的,Hijack 是个终态
Close:连接已关闭
参考:
go语言开创性的让对测试的支持成为了语言本身的重要组成部分,足以说明go语言对测试的重视以及测试本身的重要性
https://github.com/dolthub/dolt
让MySQL表也能版本管理,这个对于存储配置的数据库非常不错。
通常使用git存储配置的好处是方便查看变更历史。然而,如何让生产服务器访问却不太方便。
所以,很多时候使用MySQL存储配置,但是,查看变更历史就不那么方便了。
现在,有了dolt,简直太棒了!
1 |
setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump |
golang程序如果build时不是static的话,Linux上基本会依赖glibc的动态库的,通常也不是啥问题,但是,如果你期望一个更高版本的glibc,但是目标机器上没有,就尴尬了,这时候,其实可以编译成一个静态链接的二进制程序的,这时候需要的就是编译环境上有glibc-static,centos上的安装方法为:
1 |
yum install glibc-static -y |
那么,静态链接和动态链接后的目标文件差别会非常大吗?
1 2 3 |
# ll -h ./build/manager* -rwxr-xr-x 1 junjie20 staff 24M Feb 20 11:42 ./build/manager -rwxr-xr-x 1 junjie20 staff 28M Feb 20 11:57 ./build/manager-static |
静态链接只需要添加选项:
1 |
--ldflags '--extldflags "-static -fpic"' |
注意:
参考资料: http://tech.it168.com/a2012/0806/1381/000001381007_1.shtml
这种方式只生成aof文件;
优点: 不会定期生成snapshot,对磁盘消耗小(不是少),也不会因为生成snapshot时写磁盘对服务带来影响(虽然影响不太大)
缺点: 重新启动服务时可能需要无法估计的时间
该方式不生成aof文件,定期产生snapshot文件
优点: 重启服务时,启动速度快
缺点: 会丢失最后一次产生snapshot到意外宕机之间的写数据
1. 产生aof文件
2. 通过 bgrewriteaof 命令定期压缩aof(其实是根据内容中的数据重新生成aof)文件
优点: 不会导致aof文件太大而占用太大的磁盘文件,不会因为aof文件太大而导致重启服务时太慢
缺点: 毕竟重启服务还是要加载aof文件的
1. 定期产生snapshot文件
2. 产生snapshot文件后,删除文件中snapshot点之前的数据,这样aof就不会太大了
3. 服务重启时,先加载snapshop,在加载snapshot时间点后的aof文件
4. 这样的话,aof文件中记录的命令不应该有类似 incr decr之类的命令,应该都是set、delete之类的命令,这个和snapshot点的选择有关系(没法选择一个确切的snapshot点); 或者: snapshot期间允许用户执行写操作吗?不允许的话就没有这个问题了,如果不允许的话,这个条件也太苛刻了
5. 从redis的源码来看,是不会同时参考snapshot的rdb文件和aof文件的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
/* Function called at startup to load RDB or AOF file in memory. */ void loadDataFromDisk(void) { long long start = ustime(); if (server.aof_state == AOF_ON) { if (loadAppendOnlyFile(server.aof_filename) == C_OK) serverLog(LL_NOTICE,"DB loaded from append only file: %.3f seconds",(float)(ustime()-start)/1000000); } else { rdbSaveInfo rsi = RDB_SAVE_INFO_INIT; errno = 0; /* Prevent a stale value from affecting error checking */ if (rdbLoad(server.rdb_filename,&rsi,RDBFLAGS_NONE) == C_OK) { serverLog(LL_NOTICE,"DB loaded from disk: %.3f seconds", (float)(ustime()-start)/1000000); /* Restore the replication ID / offset from the RDB file. */ if ((server.masterhost || (server.cluster_enabled && nodeIsSlave(server.cluster->myself))) && rsi.repl_id_is_set && rsi.repl_offset != -1 && /* Note that older implementations may save a repl_stream_db * of -1 inside the RDB file in a wrong way, see more * information in function rdbPopulateSaveInfo. */ rsi.repl_stream_db != -1) { memcpy(server.replid,rsi.repl_id,sizeof(server.replid)); server.master_repl_offset = rsi.repl_offset; /* If we are a slave, create a cached master from this * information, in order to allow partial resynchronizations * with masters. */ replicationCacheMasterUsingMyself(); selectDb(server.cached_master,rsi.repl_stream_db); } } else if (errno != ENOENT) { serverLog(LL_WARNING,"Fatal error loading the DB: %s. Exiting.",strerror(errno)); exit(1); } } } |
其实, redis4.0之后,是支持rdb+aof 方式的,这时候,loadAppendOnlyFile() 函数中有rdb相关逻辑,而且,这时候的aof文件的前面部分其实就是rdb文件的内容,但是依然叫做aof文件,所以,依然时候loadAppendOnlyFile() 函数就搞定了。
参考: Redis-4.0以后的混合持久化_gdlsky的博客-CSDN博客_redis混合持久化
原来以为 save 300 10 解释为: 超过300s或者超过10条变更就snapshot,其实不是的,而是: 超过300s并且超过10条变更就snapshot
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
################################ SNAPSHOTTING ################################# # # Save the DB on disk: # # save <seconds> <changes> # # Will save the DB if both the given number of seconds and the given # number of write operations against the DB occurred. # # In the example below the behaviour will be to save: # after 900 sec (15 min) if at least 1 key changed # after 300 sec (5 min) if at least 10 keys changed # after 60 sec if at least 10000 keys changed # # Note: you can disable saving at all commenting all the "save" lines. # # It is also possible to remove all the previously configured save # points by adding a save directive with a single empty string argument # like in the following example: # # save "" save 900 1 save 300 10 save 60 10000 |
默认情况下:
1 |
curl -x ip:port http://phpor.net/ |
使用的是普通代理,就是:
如果访问https地址,就是隧道代理:
1 |
curl -x ip:port https://phpor.net/ |
如果要让http请求也是用隧道代理,则添加 -p 选项:
1 |
curl -p -x 10.222.101.37:8080 -v http://phpor.net/blog |
如果要让https请求使用普通代理呢?没有找到这个选项
c中就有typedef 就是定义一个类型别名。
typename是c++中的,只是名字上和typedef相似,有时候还挨着用,就会感觉显得啰嗦。
typename用来告诉编译器后面这个东西是个名字空间或类中定义的类型,而不是成员变量
参考:
上面的VIP专享栏,每一项都注明了VIP专享,从技术角度来看,这个属于重复的元素,很不简洁,多余的东西就得去掉;但是,从产品设计的角度来讲,重复是为了强调,就是要通过视觉来刺激你,买VIP吧,买VIP吧,买V….