分类目录归档:开发dev

python skimage图像处理

skimage即是Scikit-Image。基于python脚本语言开发的数字图片处理包,比如PIL,Pillow, opencv, scikit-image等。 PIL和Pillow只提供最基础的数字图像处理,功能有限;opencv实际上是一个c++库,只是提供了python接口,更新速度非常慢。scikit-image是基于scipy的一款图像处理包,它将图片作为numpy数组进行处理,与matlab一样。 阅读全文

LSM VS B-Tree

LSM树整个结构不是有序的,所以不知道数据在什么地方,需要从每个小的有序结构中做二分查询,找到了就返回,找不到就继续找下一个有序结构。所以说LSM牺牲了读性能。但是LSM之所以能够作为大规模数据存储系统在于读性能可以通过其他方式来提高,比如读取性能更多的依赖于内存/缓存命中率而不是磁盘读取。 阅读全文

nginx配置https

最近做点小程序,服务端api必须是https域名,配置方法如下:

创建ssh证书

自己生成CA证书:(自己生成的根证书浏览器不认,会提示不安全,但https可访问)
cd /home/openssl
openssl genrsa -des3 -passout pass:123456 -out test.pem 2048  #生成RSA私钥
openssl rsa -passin pass:123456 -in test.pem -out test.key  #提取密钥中的公钥
openssl req -new -key test.key -out test.csr -subj /C=CN/ST=beijing/L=beijing/O=YAN/CN=www.yanjingang.com #生成证书请求文件
openssl x509 -req -days 365 -in test.csr -signkey test.key -out test.crt  #生成自签名证书
openssl x509 -in test.crt -noout -text  #查看证书文件

阿里云、百度云有免费的单域名DV证书(下载注意选择nginx版本证书)

nginx配置

vim conf/vhost/php.conf
  listen 8080;      #监听8080端口http
  listen 8443 ssl;  #同时监听8443端口https
  #开启ssl并设置证书
  ssl on;
  ssl_certificate /home/openssl/www.yanjingang.crt;
  ssl_certificate_key /home/openssl/www.yanjingang.key;

重启nginx后使用https://www.yanjingang.com:8443端口访问即可(注:私人生成的证书会提示不安全,忽略即可)。

https端口转发

#80->8080、443->8443 端口转发
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443

service iptables save
iptables -L -t nat  	#查看当前nat规则
	Chain PREROUTING (policy ACCEPT)
	target     prot opt source               destination         
	REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:http redir ports 8080
	REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:https redir ports 8443

注:公网80、443、8080、8443等端口需要在aliyun安全组中入方向打开才可访问

使用https://www.yanjingang.com即可访问

看到这里满足需求的离开即可,遇到微信小程序TLS1.2问题的往后看。

在完成以上步骤后发现,https已经是安全的,百度小程序api调用也正常,但是微信小程序api调用提示“对应的服务器 TLS 为 TLS 1.0 ,小程序要求的 TLS 版本必须大于等于 1.2 。”

Nginx TLS 1.2配置

1.openSSL 版本需要 >= 1.0.2
  openssl version -a
2.nginx 版本为 0.7.65,0.8.19 及更高版本
  nginx -V
3.nginx是使用的openssl 1.0.2+编译的
  nginx -V |grep openssl
4.nginx tls1.2配置
  ssl_session_timeout 5m;
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;

实际情况是我们的server使用内部自研开发框架,nginx编译依赖很多内部插件,且使用openssl 1.0.1编译的,所以怎么设置TLS都是1.0,nginx -V如下:

解决方法:

1.长线方案
下载内部插件源码自己使用openssl1.0.2重新编译nginx
2.短线方案
使用外部openssl1.0.2编译的nginx做代理,将iptables端口删除,转发改为nginx代理转发
#设置nginx代理server
vim proxyserver/conf/proxy.conf
    #80->8080端口转发
    server {
        listen              80;
        server_name         _;

        access_log  /home/proxyserver/log/proxyserver.log;
        error_log  /home/proxyserver/log/proxyserver.log.wf;

        location / {
            proxy_set_header Host $http_host;
            proxy_set_header X-Host $http_host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X_ORIG_URI $request_uri;
            proxy_set_header CLIENTIP $remote_addr;
            proxy_set_header X-Forwarded-For-Proto https;
            proxy_set_header Https 1;

            proxy_pass http://127.0.0.1:8080;

        }
    }
    #443->8080端口转发
    server {
        listen              443 ssl;
        server_name         _;

        access_log  /home/proxyserver/log/proxyserver.log;
        error_log  /home/proxyserver/log/proxyserver.log.wf;

        #开启https ssl
        ssl on;
        ssl_certificate      /home/openssl/cert-1542784817162_www.yanjingang.com.crt;
        ssl_certificate_key  /home/openssl/cert-1542784817162_www.yanjingang.com.key;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

        location / {
            proxy_set_header Host $http_host;
            proxy_set_header X-Host $http_host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X_ORIG_URI $request_uri;
            proxy_set_header CLIENTIP $remote_addr;
            proxy_set_header X-Forwarded-For-Proto https;
            proxy_set_header Https 1;

            proxy_pass http://127.0.0.1:8080;

        }
    }
#启动代理nginx
/usr/sbin/nginx -c /home/proxyserver/conf/proxy.conf

#删除iptables端口转发
iptables -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -D PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443
service iptables save
iptables -L -t nat
#删除nginx webserver的8443端口监听和ssl配置并重启

#使用https://www.yanjingang.com验证TLS1.2和小程序调用

重启小程序开发工具后测试调用成功,收工~!

yan 18.11.21 22:00

资料:

openssl 非对称加密算法RSA命令详解:https://www.cnblogs.com/gordon0918/p/5363466.html

openssl 证书请求和自签名命令req详解:https://www.cnblogs.com/gordon0918/p/5409286.html

微信小程序要求的TLS版本大于等于1.2的问题:https://www.cnblogs.com/xjnotxj/p/7252043.html

教娃学编程—1.入门概念、int变量、if判断、函数

程序概念、int变量、if判断、函数概念

#include <stdio.h>

int main()
{
	/* YJY */
	int num = 1;
	printf("%d\n", num);
	if(num == 1){
		printf("YJY\n");
	}else{
		printf("YAN\n");
	}

	/* jiafa lianxi */
	int num1 = 89;
	int num2 = 107689;
	int result = sum(num1, num2);
	printf("%d\n", result);

   
   return 0;
}

/* sum */
int sum(int num1, int num2){
	return num1+num2;
}

2018.10.20

安全加密算法选择指南

用途 推荐使用的安全的密码算法 常见的不安全的密码算法
对称加密 AES(密钥长度>=128bits) DES、3DES、RC2、RC4
哈希算法 SHA256或以上 MD5、SHA1
非对称加密 RSA(密钥长度>=2048bits) RSA(密钥长度<=1024bits)
数字签名 RSA(密钥长度>=2048bits) RSA(密钥长度<=1024bits)
密钥交换 DH(密钥长度>=2048bits) DH(密钥长度<=1024bits)

备注:

1. AES不建议使用ECB(同样的明文总是会产生相同的密文),推荐使用CBC模式。

2. 应注意编码及加密的区别,例如base64属于编码而不属于加密。

3. 加解密中建议使用安全随机数,如java.security.SecureRandom,类Unix系统 (包括OS X):  /dev/random;不安全随机数如C标准函数random(),java.util.Random()。

4. 不建议使用私有、非标准化的加解密方式。

研发人员的3个技术方向

产品:
以业务需求为主要驱动力,其涉及到的问题往往来自于复杂的业务逻辑和功能的快速上线需求,即其难点主要来自于对产品的理解把握和需求的快速响应能力,对于大数据高并发的系统要求并非其主要考核点。典型的部门为:社区组、fe、客户系统、mi、客户端产品等。面向内部的一些需求,如一些内部平台的开发也划入此类。

工程:
以解决规模、压力等工程技术问题为主要驱动力,其涉及到的问题往往是公司大型基础平台类服务、支持业务实现在大数据量和高并发的server端服务,以及处于支持业务快速迭代而进行业务抽象构建通用服务等工作。另外,不属于算法分组,且不属于产品分组的,均可以归为工程组。这包括op、sys、qa及其他一些方向。

算法:
通过算法策略的设计调优使业务能够获得更好满意度,既包括提高准确率、召回率等优化效果的工作,也包括改进算法逻辑、降低时空复杂性等优化性能的工作。通常通过对数据的统计分析、case的跟踪分析等方法,采用规则策略和(或)统计学习等技术实现。涉及的部门包括面向各产品业务的策略团队及面向通用技术研发的基础团队,典型部门为nlp、rank、ecom策略团队等。

Kafka server.properties配置文件参数说明

每个kafka broker中配置文件server.properties默认必须配置的属性如下:

broker.id=0  
num.network.threads=2  
num.io.threads=8  
socket.send.buffer.bytes=1048576  
socket.receive.buffer.bytes=1048576  
socket.request.max.bytes=104857600  
log.dirs=/tmp/kafka-logs  
num.partitions=2  
log.retention.hours=168  
  
log.segment.bytes=536870912  
log.retention.check.interval.ms=60000  
log.cleaner.enable=false  
  
zookeeper.connect=localhost:2181  
zookeeper.connection.timeout.ms=1000000  

 

server.properties中所有配置参数说明(解释)如下列表:

参数
说明(解释)

broker.id =0
每一个broker在集群中的唯一表示,要求是正数。当该服务器的IP地址发生改变时,broker.id没有变化,则不会影响consumers的消息情况

log.dirs=/data/kafka-logs
kafka数据的存放地址,多个地址的话用逗号分割,多个目录分布在不同磁盘上可以提高读写性能  /data/kafka-logs-1,/data/kafka-logs-2

port =9092
broker server服务端口

message.max.bytes =6525000
表示消息体的最大大小,单位是字节

num.network.threads =4
broker处理消息的最大线程数,一般情况下数量为cpu核数

num.io.threads =8
broker处理磁盘IO的线程数,数值为cpu核数2倍

background.threads =4
一些后台任务处理的线程数,例如过期消息文件的删除等,一般情况下不需要去做修改

queued.max.requests =500
等待IO线程处理的请求队列最大数,若是等待IO的请求超过这个数值,那么会停止接受外部消息,应该是一种自我保护机制。

host.name
broker的主机地址,若是设置了,那么会绑定到这个地址上,若是没有,会绑定到所有的接口上,并将其中之一发送到ZK,一般不设置

socket.send.buffer.bytes=100*1024
socket的发送缓冲区,socket的调优参数SO_SNDBUFF

socket.receive.buffer.bytes =100*1024
socket的接受缓冲区,socket的调优参数SO_RCVBUFF

socket.request.max.bytes =100*1024*1024
socket请求的最大数值,防止serverOOM,message.max.bytes必然要小于socket.request.max.bytes,会被topic创建时的指定参数覆盖

log.segment.bytes =1024*1024*1024
topic的分区是以一堆segment文件存储的,这个控制每个segment的大小,会被topic创建时的指定参数覆盖

log.roll.hours =24*7
这个参数会在日志segment没有达到log.segment.bytes设置的大小,也会强制新建一个segment会被 topic创建时的指定参数覆盖

log.cleanup.policy = delete
日志清理策略选择有:delete和compact主要针对过期数据的处理,或是日志文件达到限制的额度,会被 topic创建时的指定参数覆盖

log.retention.minutes=300

log.retention.hours=24
数据文件保留多长时间, 存储的最大时间超过这个时间会根据log.cleanup.policy设置数据清除策略

log.retention.bytes和log.retention.minutes或log.retention.hours任意一个达到要求,都会执行删除

有2删除数据文件方式:

按照文件大小删除:log.retention.bytes

按照2中不同时间粒度删除:分别为分钟,小时

log.retention.bytes=-1
topic每个分区的最大文件大小,一个topic的大小限制 = 分区数*log.retention.bytes。-1没有大小限log.retention.bytes和log.retention.minutes任意一个达到要求,都会执行删除,会被topic创建时的指定参数覆盖

log.retention.check.interval.ms=5minutes
文件大小检查的周期时间,是否处罚 log.cleanup.policy中设置的策略

log.cleaner.enable=false
是否开启日志清理

log.cleaner.threads = 2
日志清理运行的线程数

log.cleaner.io.max.bytes.per.second=None
日志清理时候处理的最大大小

log.cleaner.dedupe.buffer.size=500*1024*1024
日志清理去重时候的缓存空间,在空间允许的情况下,越大越好

log.cleaner.io.buffer.size=512*1024
日志清理时候用到的IO块大小一般不需要修改

log.cleaner.io.buffer.load.factor =0.9
日志清理中hash表的扩大因子一般不需要修改

log.cleaner.backoff.ms =15000
检查是否处罚日志清理的间隔

log.cleaner.min.cleanable.ratio=0.5
日志清理的频率控制,越大意味着更高效的清理,同时会存在一些空间上的浪费,会被topic创建时的指定参数覆盖

log.cleaner.delete.retention.ms =1day
对于压缩的日志保留的最长时间,也是客户端消费消息的最长时间,同log.retention.minutes的区别在于一个控制未压缩数据,一个控制压缩后的数据。会被topic创建时的指定参数覆盖

log.index.size.max.bytes =10*1024*1024
对于segment日志的索引文件大小限制,会被topic创建时的指定参数覆盖

log.index.interval.bytes =4096
当执行一个fetch操作后,需要一定的空间来扫描最近的offset大小,设置越大,代表扫描速度越快,但是也更好内存,一般情况下不需要搭理这个参数

log.flush.interval.messages=None

例如log.flush.interval.messages=1000

表示每当消息记录数达到1000时flush一次数据到磁盘
log文件”sync”到磁盘之前累积的消息条数,因为磁盘IO操作是一个慢操作,但又是一个”数据可靠性”的必要手段,所以此参数的设置,需要在数据可靠性与”性能”之间做必要的权衡.如果此值过大,将会导致每次”fsync”的时间较长(IO阻塞),如果此值过小,将会导致“fsync”的次数较多,这也意味着整体的client请求有一定的延迟.物理server故障,将会导致没有fsync的消息丢失.

log.flush.scheduler.interval.ms =3000
检查是否需要固化到硬盘的时间间隔

log.flush.interval.ms = None

例如:log.flush.interval.ms=1000

表示每间隔1000毫秒flush一次数据到磁盘
仅仅通过interval来控制消息的磁盘写入时机,是不足的.此参数用于控制“fsync”的时间间隔,如果消息量始终没有达到阀值,但是离上一次磁盘同步的时间间隔达到阀值,也将触发.

log.delete.delay.ms =60000
文件在索引中清除后保留的时间一般不需要去修改

log.flush.offset.checkpoint.interval.ms =60000
控制上次固化硬盘的时间点,以便于数据恢复一般不需要去修改

auto.create.topics.enable =true
是否允许自动创建topic,若是false,就需要通过命令创建topic

default.replication.factor =1
是否允许自动创建topic,若是false,就需要通过命令创建topic

num.partitions =1
每个topic的分区个数,若是在topic创建时候没有指定的话会被topic创建时的指定参数覆盖

以下是kafka中Leader,replicas配置参数

controller.socket.timeout.ms =30000
partition leader与replicas之间通讯时,socket的超时时间

controller.message.queue.size=10
partition leader与replicas数据同步时,消息的队列尺寸

replica.lag.time.max.ms =10000
replicas响应partition leader的最长等待时间,若是超过这个时间,就将replicas列入ISR(in-sync replicas),并认为它是死的,不会再加入管理中

replica.lag.max.messages =4000
如果follower落后与leader太多,将会认为此follower[或者说partition relicas]已经失效

##通常,在follower与leader通讯时,因为网络延迟或者链接断开,总会导致replicas中消息同步滞后

##如果消息之后太多,leader将认为此follower网络延迟较大或者消息吞吐能力有限,将会把此replicas迁移

##到其他follower中.

##在broker数量较少,或者网络不足的环境中,建议提高此值.

replica.socket.timeout.ms=30*1000
follower与leader之间的socket超时时间

replica.socket.receive.buffer.bytes=64*1024
leader复制时候的socket缓存大小

replica.fetch.max.bytes =1024*1024
replicas每次获取数据的最大大小

replica.fetch.wait.max.ms =500
replicas同leader之间通信的最大等待时间,失败了会重试

replica.fetch.min.bytes =1
fetch的最小数据尺寸,如果leader中尚未同步的数据不足此值,将会阻塞,直到满足条件

num.replica.fetchers=1
leader进行复制的线程数,增大这个数值会增加follower的IO

replica.high.watermark.checkpoint.interval.ms =5000
每个replica检查是否将最高水位进行固化的频率

controlled.shutdown.enable =false
是否允许控制器关闭broker ,若是设置为true,会关闭所有在这个broker上的leader,并转移到其他broker

controlled.shutdown.max.retries =3
控制器关闭的尝试次数

controlled.shutdown.retry.backoff.ms =5000
每次关闭尝试的时间间隔

leader.imbalance.per.broker.percentage =10
leader的不平衡比例,若是超过这个数值,会对分区进行重新的平衡

leader.imbalance.check.interval.seconds =300
检查leader是否不平衡的时间间隔

offset.metadata.max.bytes
客户端保留offset信息的最大空间大小

kafka中zookeeper参数配置

zookeeper.connect = localhost:2181
zookeeper集群的地址,可以是多个,多个之间用逗号分割 hostname1:port1,hostname2:port2,hostname3:port3

zookeeper.session.timeout.ms=6000
ZooKeeper的最大超时时间,就是心跳的间隔,若是没有反映,那么认为已经死了,不易过大

zookeeper.connection.timeout.ms =6000
ZooKeeper的连接超时时间

zookeeper.sync.time.ms =2000
ZooKeeper集群中leader和follower之间的同步实际那

转自:http://blog.csdn.net/lizhitao/article/details/25667831

python使用esmre代替ahocorasick实现ac自动机[多模匹配]

为什么会用AC自动机? 如果你想知道一篇文章有没有你要过滤的敏感词,怎么办? 不可能用正则一个个的匹配吧?  敏感词超过300个之后,用Trie来构建模式树 (字典树)的速度优势相当的明显… …

特别说下,trie图也是一种DFA,可以由trie树为基础构造出来,对于插入的每个模式串,其插入过程中使用的最后一个节点都作为DFA的一个终止节点。

如果要求一个母串包含哪些模式串,以用母串作为DFA的输入,在DFA 上行走,走到终止节点,就意味着匹配了相应的模式串。

ps: AC自动机是Trie的一种实现,也就是说AC自动机是构造Trie图的DFA的一种方法。还有别的构造DFA的方法…

不扯淡了,我们后端都是python写的,python的ahocorasick模块跟我们的业务不太匹配,问题是这样的 !    如果你的服务是用来做敏感词匹配,也就是说所有文章里面只要含有一个关键词,那就说明匹配了。  但是我们的业务是文章中的所有能匹配到的关键词都一一的抽取出来。   我想有些朋友可能还不太明白,那么我举个例子, 如果我的关键词里面有宝马和马,那么用python的ahocorasick库只会得到宝马,而不会得到马。  问题是处在马这个字节是在宝马的链条里面的。  如何避开这个问题,我们也懒得自己重写了,已经有人给出了解决的模块。  已经测试完成,并上线使用了。

安装简单,直接pip install esmre

import esm
index = esm.Index()
index.enter("宝马")
index.enter("马")
index.enter("奔驰")
index.enter("保时捷")
index.fix()
index.query("哎呀,今天在楼下看到了宝马,我老家倒是有养马的,以前的邻居有个奔驰,不对是保时捷,大爷的,都是马")

再来一个完整的例子.  后续有时间我会把ac自动机的服务集成到rpc服务里面,然后用docker打包。

#coding:utf-8
import esm
index = esm.Index()
with open('keyword.config','r') as f:
    for i in f.readlines():
        index.enter(i.strip())
    index.fix()
 
str = """
head&shoulders海飞丝Hershey‘s
Loreal欧莱雅LUX2
力士
L’OREALMagic2
美即
MysteryCity
谜城
NO.1BABY2
RESIN
SANXIAO
SHISEIDO FINE TOILETRY2
SKII美之匙
Tao yu tang2
淘雨堂
whoo倍加洁
卡尔林奈
娇韻诗
德国帮宝适
Perfect puff2
See Young2
落健
高夫
"""
data = index.query(str)
print data

测了几天,性能还是可以的,500KB的文章,6000多个关键词,消耗的时间在0.002左右,相比ahocorasick一点都不差的。  观察了下,esmre是没有发现内存异常泄露等问题。

[2015-06-12 23:34:01,043] INFO extractor "Get keywords takes 0.0003 seconds"
[2015-06-12 23:34:01,069] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:01,178] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:02,372] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:02,386] INFO extractor "Get keywords takes 0.0012 seconds"
[2015-06-12 23:34:02,631] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:03,656] INFO extractor "Get keywords takes 0.0021 seconds"
[2015-06-12 23:34:03,744] INFO extractor "Get keywords takes 0.0001 seconds"
[2015-06-12 23:34:03,785] INFO extractor "Get keywords takes 0.0001 seconds"
[2015-06-12 23:34:03,910] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:04,031] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:05,004] INFO extractor "Get keywords takes 0.0035 seconds"
[2015-06-12 23:34:05,579] INFO extractor "Get keywords takes 0.0055 seconds"
[2015-06-12 23:34:05,602] INFO extractor "Get keywords takes 0.0005 seconds"
[2015-06-12 23:34:05,662] INFO extractor "Get keywords takes 0.0010 seconds"
[2015-06-12 23:34:06,125] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:06,299] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:06,404] INFO extractor "Get keywords takes 0.0003 seconds"
[2015-06-12 23:34:07,396] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:07,595] INFO extractor "Get keywords takes 0.0004 seconds"
[2015-06-12 23:34:08,725] INFO extractor "Get keywords takes 0.0015 seconds"
[2015-06-12 23:34:09,504] INFO extractor "Get keywords takes 0.0004 seconds"
[2015-06-12 23:34:09,515] INFO extractor "Get keywords takes 0.0005 seconds"
[2015-06-12 23:34:10,650] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:11,206] INFO extractor "Get keywords takes 0.0003 seconds"
[2015-06-12 23:34:12,298] INFO extractor "Get keywords takes 0.0002 seconds"
[2015-06-12 23:34:12,319] INFO extractor "Get keywords takes 0.0001 seconds"
[2015-06-12 23:34:13,547] INFO extractor "Get keywords takes 0.0006 seconds"
[2015-06-12 23:34:13,853] INFO extractor "Get keywords takes 0.0005 seconds"

 

摘自: http://xiaorui.cc   http://xiaorui.cc/?p=1649