ops

records of learning.

Tomcat 7.0.76 Invalid character found in the request target

故障现象 升级tomcat至7.0.76后,GET请求的参数中含有中文时tomcat返回400错误,tomcat错误日志如下 java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986 at org.apache.coyote.http11.InternalNioInputBuffer.parseRequestLine(InternalNioInputBuffer.java:317) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1000) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1756) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1715) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:662) 原因 查询Changelog得知,tomcat 7.0.73版本添加了Add additional checks for valid characters to the HTTP request line parsing so invalid request lines are rejected sooner导致。 解决方法 请求前自行转义 更换tomcat为较低版本(不过tomcat的这次更改是依据RFC7230 and RFC 3986,在往后的版本,不会移除该特性)

不重启解决Too Many Connections

当发生Too many connections时,即使是DBA也无法登录到数据库,一般的做法是修改配置文件的max_connections参数,然后重启数据库,这样业务就有几秒钟的中断,对于线上不能中断的数据库就只能采用另外一种极客的方法了,用gdb直接修改mysqld内存中max_connections的值,具体做法如下: gdb -p $(cat /data/mysql/mysql-server.pid) -ex "set max_connections=3000" -batch 改进方法如下 通常有两个参数控制控制最大连接数: max_connections:该实例允许最大的连接数 max_user_connections:该实例允许每个用户的最大连接数 每个人要根据自己业务量,设置合适的值,不要盲目设置过大,但也不可设置过小,因为MySQL在连接数上升的情况下性能下降非常厉害,如果需要大量连接,这时可以引入thread_pool,所以我们需要保持一个原则:系统创建的用户(给应用使用用户)数 * max_user_connections < max_connections。

在 OpenResty 中使用正则表达式

在 OpenResty 中使用正则表达式,社区中推荐的做法是使用ngx.re api。比如匹配一个字符串是否为 http(s) 的链接,可以这么写: local function is_http_url(s) return ngx.re.find(s, [[^https?://[\w-_?.:/+=&#%]+$]]) end 压测一下: local t = os.clock() for _ = 1, max do is_http_url("http://blog.stackoverflow.com/2016/10/Stack-Overflow-92-Podcast-The-Guerilla-Guide-to-Interviewing/?cb=1") end print("Time cost: ", os.clock() - t, " s") 结果:Time cost: 2.663408 s 另一种做法是使用 lua 的正则语法: local function is_http_url(s) return s:find("^https?://[%w-_%.%?:/%+=&#%%]+$") end 结果:Time cost: 0.652221 s 呃,怎么前者耗时是后者的四倍?lua 内置的小小状态机实现,居然打败了大名鼎鼎的 PCRE 库!说好的社区推荐呢! 仔细一瞧,前者的确漏了点东西。ngx.re默认不会缓存正则表达式编译后的结果。一般在其它编程平台上,我们都会先把字符串编译成正则表达式,再用到正则函数中。比如在 Python 里使用 re.compile。所以赶紧补上: return ngx.re.find(s, [[^https?://[\w-_?.:/+=&#%]+$]], "o") 好,这次性能有了明显提升:Time cost: 0.646518 s

[python]统计列表中重复项的出现次数

列表项由数字、字符串组成,统计重复项 >>> from collections import defaultdict >>> d = defaultdict(int) >>> for x in [1, 2, 3, 1, 2, 3, 1]: ... d[x] += 1 ... >>> dict(d) {1: 3, 2: 2, 3: 2} >>> >>> c = defaultdict(int) >>> for y in ['a', 'b', 'a', 'c', 'c']: ... c[y] += 1 ... >>> dict(c) {'a': 2, 'c': 2, 'b': 1} 列表项由字典组成,统计某一键值的重复数 >>> e = defaultdict(int) >>> for x in [{'a': 1, 'b': 1}, {'a': 2, 'b':1}, {'a': 1, 'c': 3}]: .

Ceph核心概念备忘录

scrub ceph-osd会定义启动scrub线程,扫描部分对象(哪些对象?),和其他副本比较,发现是否一致。如果发现不一致,ceph会抛出这个异常给用户解决。以PG为粒度,触发scrub。用户手动修复,使用: ceph pg repair <pg_id> # 全量复制master节点数据到副本节点。 scrub分为light scrubbing和Deep scrubbing,前者是频率多直接检查hash值,后者是频率少直接读取内容计算checksum比较。 backfill 当加入或者减少一个新的osd时,所有remapped之后的PG都要迁移到该osd上,此时就叫做backfill。 recovery 当一个osd或者多个osd崩溃之后,再次上线,该osd的状态已经严重滞后了(此时crushmap中还保持该osd),这个时候就会进行recovery过程。如果是多个osd recovery, 那么这个时候会占用非常多的服务器资源。 peering 故障恢复时,对比各个副本的PGlog, 根据PGlog差异构造missing列表,恢复阶段根据missing列表来恢复。peering以PG为单位进行,peering过程中,改PG的IO会被挂起,进入recovery阶段,则可以接受IO,但hit到missing列表项的,也会挂起,直到恢复完成后。因为PGlog的记录是有限的,当peering时发现,PGlog差异太大,则会触发backfill。 active + clean PG的status,active的意思是说该PG可以接受读写请求,clean的意思是说PG的副本数达到了要求。 degrade PG的副本数没有达到要求,但是满足最小副本数要求。 incomplete PG的副本数连最小副本数都没有达到。 inconsistent scrub或者deep scrub的时候发现PG内容不一致。 down 关键数据丢失。进入这个状态的一种方法,比如一个PG有两个副本,先down掉其中的一个osd,再down掉第二个osd,最后把第一个osd起起来,这样这个PG就处于down状态。 PGlog和日志文件系统 PGlog相当于undo log, journal相当于redo log。一个是在某个操作执行完成之后,做log记录,如果操作成功,则可以undo;另一个是在某个操作执行之前,做log记录,如果操作失败,下次可以redo。

ceph pgs inconsistent

OSD扩容后出现如下错误 HEALTH_ERR 2 pgs inconsistent; 320 scrub errors [root@ceph01 ~]# ceph health detail HEALTH_ERR 2 pgs inconsistent; 320 scrub errors pg 10.9 is active+clean+inconsistent, acting [6,0,9] pg 10.10 is active+clean+scrubbing+deep+inconsistent, acting [2,6,4] 320 scrub errors 修复处于不一致状态的pgs [root@ceph01 ~]# ceph pg repair 10.9 instructing pg 10.9 on osd.6 to repair [root@ceph01 ~]# ceph pg repair 10.10 instructing pg 10.10 on osd.2 to repair 经过一段时间的修复后,ceph恢复正常。

删除osd的正确方式

按照官网的步骤走的话,在 标记osd为out 和 从crushmap删除osd 这两步都会触发数据再平衡,如下方式只触发了一次迁移,建议使用。 调整osd的crush weight ceph osd crush reweight osd.0 0.1 说明:这个地方如果想慢慢的调整就分几次将crush 的weight 减低到0 ,这个过程实际上是让数据不分布在这个节点上,让数据慢慢的分布到其他节点上,直到最终为没有分布在这个osd,并且迁移完成这个地方不光调整了osd 的crush weight ,实际上同时调整了host 的 weight ,这样会调整集群的整体的crush 分布,在osd 的crush 为0 后, 再对这个osd的任何删除相关操作都不会影响到集群数据的分布。 停止osd进程 systemctl stop ceph-osd@0 这个是通知集群这个osd进程不在了,不提供服务了,因为本身没权重,就不会影响到整体的分布,也就没有迁移 将节点状态标记为out ceph osd out osd.0 这个是通知集群这个osd不再映射数据了,不提供服务了,因为本身没权重,就不会影响到整体的分布,也就没有迁移 从crush中移除节点 ceph osd crush remove osd.0 这个是从crush中删除,因为已经是0了 所以没影响主机的权重,也就没有迁移了 删除节点 ceph osd rm osd.0 这个是从集群里面删除这个节点的记录 删除节点认证(不删除编号会占住) ceph auth del osd.0 这个是从认证当中删除这个节点的信息

Centos 7.x systemd对比Centos 6.x daemon

从CentOS 7.x开始,CentOS开始使用systemd服务来代替daemon,原来管理系统启动和管理系统服务的相关命令全部由systemctl命令来代替。 1、原来的 service 命令与 systemctl 命令对比 daemon命令 systemctl命令 说明 service [服务] start systemctl start [unit type] 启动服务 service [服务] stop systemctl stop [unit type] 停止服务 service [服务] restart systemctl restart [unit type] 重启服务 此外还有二个systemctl参数没有与service命令参数对应 status: 参数来查看服务运行情况 reload: 重新加载服务,加载更新后的配置文件(并不是所有服务都支持这个参数,比如network.service) 应用举例: #启动网络服务 systemctl start network.service #停止网络服务 systemctl stop network.service #重启网络服务 systemctl restart network.service #查看网络服务状态 systemctl status network.

MySQL Unable to lock ibdata1 error 11 fix

A bad shutdown can cause such erros on MySQL. InnoDB: Unable to lock ./ibdata1, error: 11 InnoDB: Check that you do not already have another mysqld process InnoDB: using the same InnoDB data or log files. InnoDB: Error in opening ./ibdata1 For solution mv ibdata1 ibdata1.bak cp -a ibdata1.bak ibdata1 service mysqld restart

ceph集群jewel版本部署osd激活权限报错

环境 ceph version 10.2.2 (45107e21c568dd033c2f0a3107dec8f0b0e58374) ceph-deploy 1.5.34 ceph集群jewel版本部署过程中执行osd激活操作如下 ceph-deploy osd activate ceph13:/dev/sdb1:/dev/sda2 报错内容如下 [2016-07-29 00:05:19,106][ceph_deploy.conf][DEBUG ] found configuration file at: /root/.cephdeploy.conf [2016-07-29 00:05:19,107][ceph_deploy.cli][INFO ] Invoked (1.5.34): /bin/ceph-deploy osd activate ceph13:/dev/sdb1:/dev/sda2 [2016-07-29 00:05:19,107][ceph_deploy.cli][INFO ] ceph-deploy options: [2016-07-29 00:05:19,108][ceph_deploy.cli][INFO ] username : None [2016-07-29 00:05:19,108][ceph_deploy.cli][INFO ] verbose : False [2016-07-29 00:05:19,108][ceph_deploy.cli][INFO ] overwrite_conf : False [2016-07-29 00:05:19,108][ceph_deploy.cli][INFO ] subcommand : activate [2016-07-29 00:05:19,108][ceph_deploy.cli][INFO ] quiet : False [2016-07-29 00:05:19,108][ceph_deploy.cli][INFO ] cd_conf : <ceph_deploy.