Microsoft Excel的坑:数据处理方面

首先一个不可否认的事实:Microsoft Excel是个使用简便、功能丰富的数据处理工具;但这不能掩饰它本身的不少缺陷,本文只讲其在数据转换时的陷阱,就是“坑”。

脑残的转义约定:双引号转义、不转义换行符

csv是常用的数据交换格式,但excel生成的csv文件却有几个脑残的约定(大概是微软自己的历史包袱所致),通常excel使用双引号括起来字段内容,如果字段内容中有双引号,则使用 \" 代替;还有其他特殊符号,也会做相应转义。所以,使用excel转换数据(如导入到MySQL)时,要注意处理这些问题。

换行符转义。可以事先在excel中替换,excel查找格里先清空格中内容,按几次Backspace再按几次Delete,确保真正的清空。按住Alt键不松开,输入数字10,此时格里没有任何显示,然后在替换格中输入\n,全部替换,即完成换行符的转义。

双引号转义。这个问题有点恶心。1)如果对内容一致性要求不高,可以将双引号完全删除(查找替换成空字符串)。2)将双引号替换成一个其他字符串(比如~^这类特殊字符、或者~~这样的组合字符串),事先在excel文件里查找、以确保该字符串不会在内容中出现。保存成csv后,再将该保护字符串替换成\",完成转义替换。

 Excel表导入MySQL的几个可选方案

导数据前一般需要事先建好目标表,目标表的字段长度可以适当大一此,避免导入失败。或者通过事先计算每个字段的最大长度,比如用awk 参考。下面是几种导入方法,按操作难度从易到难排列

  • 使用第三方工具(如navicat 等)直接导入,但不少时候会报错,而且原因不明。
  • excel转为csv,通过phpMyAdmin或Load Data等导入MySQL。
  • excel公式构造一系列insert 语句,拿到mysql里执行(粘贴到客户端里运行,或保存到文件让mysql加载)。
  • excel导入到ms access(微软自家产品内部有良好兼容性),再使用navicat等第三方工具导到mysql。
  • 自己写脚本处理。

后面只是几张图,随便参考一下吧。

navicat导excel到mysql报错

navicat导excel到mysql报错

vlookup函数匹配到空格,但返回结果却是 0

解决方案:vlookup函数结果拼接上个空格,比如  =vlookup(C1,sheet2!A:F,5,0)&""

EOF

windows下安装zip压缩版的mysql服务器端v5.7.16(另MariaDB 10.4.10)

环境:windows 10某个版本(写本文的最新版本)

目的:安装个mysql服务端,从官方下载的zip压缩版5.7.16,而不是msi版本。

操作过程折腾了,以前安装过多次,不过好像不是真正意义上的从zip安装,而是使用之前通过msi安装过的版本,后面只是注册成系统服务一项。

本次折腾的的操作,主要从官方是下载.zip版本压缩包,选择的是x64版,解压缩到合适的目录里,本文以 C:\Program Files\mysql\  为例。

step 0. 准备配置文件:复制my-default.ini得到my.ini ,修改其中的basedir, datadir两个参数,示例如下

basedir = C:\Program Files\mysql
datadir = D:\data\mysql-data

step 1. 安装为windows服务:管理员身份启动cmd,进入mysql/bin/目录,执行如下安装命令:

mysqld --install MySQL --defaults-file="C:\Program Files\mysql\my.ini"

注意:--install 参数必须在前,否则mysqld会认为你要运行mysqld进程,然后启动失败)

setp 2. 初始化数据目录:创建 D:\data\ ,注意不需要创建mysql-data子目录;运行 mysqld --initialize

step 3. 查root用户初始密码:查windows日志-应用程序日志,里面应该有类似如下一条

A temporary password is generated for root@localhost: 5cuiMezaNd>QFor more information....

其中5cuiMezaNd>Q即是默认密码,到命令行里修改一下吧,如下一行,将root密码改为000111, 会有交互提示输入旧密码的。

mysqladmin.exe -uroot -p password "000111"

step 4. 启动windows服务:net start MySQL. 完工。

Addition. 如需要卸载服务,到mysql/bin/目录里执行 mysqld.exe --remove 即可。需要的话删除mysql数据文件目录。

附一篇:Windows 下安装MariaDB 10.4.10

1. 下载windows版的zip包,解压缩到合适位置,以下假定为 C:\Program Files\MySQL\mariadb-10.4.10-winx64

2. 初始化数据目录,使用 mysql_install_db.exe 命令,(这与mysql的 mysqld --initialize 命令不同),最主要的是指定数据目录参数datadir、root用户密码

mysql_install_db.exe --datadir="D:/data/mysql-data/" -p 000111 -P 3306

3. 准备配置文件。把datadir下生成的my.ini剪切到mariadb-10.4.10-winx64下,按需要修改配置参数,如加入复制、innodb优化等参数。

4. 注册服务,完成。mysqld --install MySQL --defaults-file="...ini"

 

MySQL复制设置及相关维护操作

主从复制配置步骤

1. 主库服务器配置

主服务器MySQ配置参数,参数主要依据《高性能MySQL 第三版》;从服务器配置与此稍有不同,主要是增加几个参数,如后节。

#replication
server-id=100
log-bin=mysql-bin
expire_logs_days=30
sync_binlog=1
relay_log=mysql-relay-bin
log_slave_updates=1

#replication safe for innodb engine
innodb_flush_logs_at_commit
innodb_support_xa=1

服务器id号;设置二进制日志文件名(隐含启用);binlog文件过期天数(最大允许99,设为0则不过期);每次写入binlog后同步到磁盘。接下几个参数实际是slave上使用的(参看文slave的配置所述),写在这里可以让主从配置参数都一致,方便实际使用时少出错,也方便多级式的复制拓扑。

2. 添加复制用户

只需要赋两个全局的权限: REPLICATION SLAVE, REPLICATION CLIENT

CREATE USER 'repl'@'192.168.10.132' IDENTIFIED BY '***';
GRANT REPLICATION SLAVE , REPLICATION CLIENT ON * . * TO 'repl'@'192.168.10.132' IDENTIFIED BY '***';

3. 备份主库,备份中加入binlog及位置

全面备份主库,备份前需要已经启用二进制日志。

mysqldump -hlocalhost --opt --master-data=1 --all-databases --max_allowed_packet=8M --net_buffer_length=128K -uroot -pyour-password >all.sql

为了获得一致性的备份,考虑加入参数--single-transaction 或 --lock-all-tables,分别针对事务型引擎及非事务型引擎,但它们不能同时使用。

注意其中--master-data=1参数,它将binlog及位置信息生成到备份文件中,大概如下一行

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=8747725;

4.iptables放行备库连入

允许从服务器ip到主服务器3306端口的连接

iptables -I INPUT 7 -s 192.168.10.132/32 -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT

5. 配置从服务器

server-id=201
log-bin=mysql-bin
expire_logs_days=30
sync_binlog=1
relay_log=mysql-relay-bin
log_slave_updates=1     # actually only for B in A->B->C 
read_only=1

前四个与主配置一样;中继日志写入binlog (默认是不写的,这实在有点出乎意料);中继日志文件名;数据只读(root用户不在此限)

6. 还原到从库服务器上

SOURCE /path/to/bakup.sql;

6. 配置从库,连接到主库

事实上下面的log_file,log_pos可以不用再指定,因为当初的备份里已经有该信息。当然这里再指定一次也没负作用。

change master to master_host='192.168.10.100', 
master_user='repl',
master_password='repl-password', 
master_log_file='mysql-bin.000004', 
master_log_pos=8747725;

7. 启动slave

start slave

顺利的话即完成。

如报 Failed to open the relay log 的错误,先停止slave的mysql服务,删除 /var/lib/mysql/ 下的中继日志相关文件,主要是  *-relay-bin.* 及 relay-log.info,再启动重新start slave

配置中的一些注意事项

  • 关于binlog_format 参数。该参数的默认值很可能是STATEMENT。它会造成一些问题,比如 insert into tablename select ... limit n 这样的语句,执行时会报warning错误,原因是limit结果在一致性上是非安全的。所以可以加入 binlog_format=MIXED 或者 binlog_format=ROW 的配置参数 。
  • 至少在 Mariadb 5.5 上,RESET SLAVE 似乎并不起效,而要写成RESET SLAVE ALL; 才行。
  • 如果是同时是主与从的服务器上,必须加入参数 log_slave_updates ,因为,MySQL默认不把中继日志写入二进制日志里(结果就是下级从库收不到相关binlog)。这实在出乎意料。

日常管理维护相关

查看二进制日志文件

即,查看 data 目录下都有哪些binlog文件,通过 SHOW BINARY LOGSSHOW MASTER LOGS 语句,二者等价。还有中继日志,这个好像没有相关语句,要看只能到磁盘目录里看了。

查看二进制日志内容

可以通过SHOW BINLOG EVENTS语句,或者mysqlbinlog工具进行查看日志内容,即是每条binlog事件干了什么

> SHOW BINLOG EVENTS IN 'mysql-bin.000015' LIMIT 0, 30    # 这是sql语句
$ mysqlbinlog -vv mysql-bin.000016       # 注意,这是个可执行程序,跟 mysqldump 类似安装在bin目录中

刷新二进制日志

(这里flush的翻译为刷新不好,叫滚动日志文件更好。)刷新并终结当前的binlog二进制日志文件的写入,并开启一个新的二进制日志文件  FLUSH BINARY LOGS;   。

如果要刷新中继日志,则 FLUSH RELAY LOGS;(中继日志,一般不需要理它,事实上它主要由 chagne master ... 时会自动重设,一般不要手工指定)

自动定时清理binlog

通过参数 expire_logs_days 指定过期天数,过期自动清理;最大只允许99天,具体天数据按实际情况定(空间与同步延迟等)。该参数还可运行时设定。

手工清理binlog

mysql的root用户登录客户端,执行purge命令。

> PURGE {MASTER | BINARY} LOGS TO 'log_name'
> PURGE {MASTER | BINARY} LOGS BEFORE 'date'

其中 log_name是show master logs; 显示的日志文件名,如 mysql-bin.000001. 应用举例:

> PURGE MASTER LOGS TO 'mysql-bin.000003';  //清除mysql-bin.000003(含)之前的日志
> PURGE MASTER LOGS BEFORE '2016-11-05 10:00:00';   //清除2016-11-05 10:00:00前的日志
> PURGE MASTER LOGS BEFORE DATE_SUB(NOW(),INTERVAL 3 DAY);
  //清除3天前日志,使用BEFORE函数计算日期,变量的date自变量还可以为'YYYY-MM-DD hh:mm:ss'格式。详查手册

清理二进制日志的影响。如果当前服务器有一个活跃的从属服务器,该从服务器当前正在读取您正在试图删除的日志之一,则本语句不会起作用,而是会失败,并伴随一个错误。不过,如果从属服务器是休止的,并且您碰巧清理了其想要读取的日志之一,则从属服务器启动后不能复制。当从属服务器正在复制时,本语句可以安全运行。您不需要停止它们。(参考

正常运行若干时间后的复制失败后的维护

如果正常复制运行一段时间以后,出现了异常(通常时进程异常结束、断电等),复制故障了,这里通过 SHOW SLAVE STATUS 可以看到 slave状态里有报执行错误的语句,可以据些解决。如果不奏效,或许需要重配置slave才可以解决问题,

stop slave;
SOURCE /path/to/bakup.sql;
RESET SLAVE ALL;
change master to ...
show slave status; #检查状态,确认主库及连接账号等
START SLAVE;

如果确认可以无视相关错误而继续往后执行,则这时可以设置变量 SET GLOBAL sql_slave_skip_counter = N 跳N个binlog事件。这里有个小技巧,可以一次性把N设置得大一些,如果后面的事件可以正常执行了,再把这这个变量归0(要先停掉 slave ,再设0,再启动slave)。

深入二进制日志

binlog的传递

假定有三台服务器,设置成级联的主从复制,A->B->C,有一条binlog事件在A生成。通过SHOW BINLOG EVENTS语句查看binlog日志内容时,可以看到其中的一列“Server_id”;亦即配置文件里的server-id。该条事件在经过B传递给C,其中的服务器id是保持不变的;事件信息Info也是不变的,直接传给下级slave。这里并不是说,原事件在B上重放时,再生成一次,然后把新生成的传递下去。也正是因此,才可以把B配置成binlog日志服务器(即把B上的表设置成blackhole引擎,这样B上的表里没有数据,而只有binlog),专用做binlog日志分发。

binlog的内容及存储占用

事实上ROW格式的binlog事件也一样可以认为是相关的sql语句,主要ddl 及 insert, update, delete等,但深入探查一下,会发现 update 的相关的binlog 里,同时包含了更新前后的所有字段的值,也就是整行数据。所以,字段多且长的表,如果频繁update,binlog将占用更多的磁盘空间。类似的,删除行的delete操作,也记录了完整的数据。(参看手册

这也很出乎意料,可能我们原本会以为,只需要通过主键追踪有更新的字段即可,却并不是。大概,这是为了适应主键不一致或没有主键的情况,主库生成binlog时不要做判断,只管无脑的做记录,当slave重放时由sql线程决定是否用主键。

不同主键情况的影响表现

经实验表明(也就是说,手册中没有找到相关的官方说明),slave的sql进程在重放事件时,对于update与delete两类事件,相当于执行一条update或delete语句,其中where条件包括了所有列,即,所有字段都同时匹配的行。这很自然。但,如果本地表有主键或惟一键,那么只按其做更新,而不管其他列。这也可以理解,毕竟有惟一键就不用全表扫描了。

不过,深入想一下,如果主从库的惟一键并不一致,那么,就会造成一些奇异的表现。有时或许当“特性”而hack利用。

亚马逊kindle电子书促销活动误单申诉聊天记录

我: kindle电子书促销
您现在已连接到亚马逊的 刘晓龙。
刘晓龙: 您好,目前为您解答的是亚马逊售前客服,为了给您提供更专业的服务支持,我们将帮您在线转接到kindle服务团队,随后聊天的窗口会变为灰色,请您不要关闭窗口,稍加等待,谢谢!
客户服务联盟伙伴随后将与您联系。
您现在已连接到亚马逊的 Xue。
Xue: 您好,我是亚马逊kindle客服谭雪,很高兴为您服务。^ω^
我: 您好,今天的1.99元电子书促销活动里,最后两单有疑问
Xue: 您是收到短信的通知购买的电子书是吧?
我: 是的
购买时,显示的是原价
最后一步付款时,扣的才是1.99元
买过第一本书确认过这一点后,后面的购买是直接一键下单了
Xue: 最后您的书是花费原价购买的吗?
我: 前面大概只购买了六本书,是1.99元,没有问题,但后面两本却是原价
Xue: 因为咱们的书的数量有限,您购买的原价是此书已经没有了。我帮您进行退款可以吗?
我: 这不是我的预期,能否退款吗
麻烦你了,退款吧
Xue: 没事的啊哈
您稍等
我: 感觉你们这个活动准备得不够充分
Xue: D01-6669538-9093325
D01-2528073-4094901
这两个订单吗?
我: 是这两单
促销品售完时,要有必要提示提示,不然给客户带来麻烦,对亚马逊品牌形象也不好
Xue: 已经帮您申请退款了。
我: 谢谢了
Xue: 嗯嗯,很抱歉给您带来的不便,这边我和领导反馈一下。
O(∩_∩)O还有其他的可以帮到您的吗?
我: 别的没有了,麻烦你了
Xue: 没事的哈
◕‿‿◕。)づ 有任何问题随时联系我们哦!
我: 好的,祝你周末快乐~~
Xue: 谢谢您,您也是哦~
我: 订单编号 D01-9999216-5336547
Xue: 这个是没有付款的订单
我: 这一单,我是测试一下价格的,是否需要麻烦删除一下啊
对的,只是测试一下
Xue: 嗯嗯,已经帮您取消了
我: 如果没有影响,不管也可以
嗯,谢啦
Xue: 没事的哈,我已经帮您取消了
我: 谢谢,不打扰你了~~~
Xue: 没事的哈。很高兴可以帮到您哦
感谢您对亚马逊的支持,聊天窗口即将关闭,在聊天结束后您可以继续查看聊天记录。希望我的服务能够帮助到您,感谢您对亚马逊Kindle的关注和支持。再见!
Kindle在,书未老~
【亚马逊Kindle现已开通微信公众号服务,搜索微信公众号“cn_Kindle”进行关注,我们会为您推送关于Kindle设备和电子书的最新消息,更有夜读打卡、Send to Kindle及在线客服等功能。您也可以点击公众号菜单及时获取相关信息和服务。】

 

jingdong_online_service_chat_161017

本博客正式支持HTTPS/SSL浏览(powered by Let's Encrypt)

今天起,本博客已经正式启用https/ssl,页面上链接已经更新为https链接。

使用的是Let's Encrypt提供的免费ssl证书服务。

Let's Encrypt服务优势

免费、支持多域名、国际化,并且服务商是Linux基金会成员,可信度高。

目前主流浏览器都支持该证书的,参看官方的“证书兼容列表”

负面影响评估

以GA上最近1万(准确数字是10523)次会话作样本做评估,GA只计算“人”的访问,而不计蜘蛛,这更符合现实。(可以认定,主流的搜索引擎蜘蛛应该是支持该证书的,这个影响按理可以忽略。)

按网友的经验IE6是不支持的,经过虚拟机下windows 2003里IE6测试证实了这一点(手上没带IE6的xp)。样本会话中共计10次IE6,9次IE7;由此IE6占比不到0.1%即使带上IE7,也不到0.2%. 因此旧版IE可以忽略。

Safari 4.0以下无访问。

 

Let’s Encrypt HTTPS证书申请部署与自动续期/免费ssl,nginx,centos

前言/絮叨

一年半以前曾经买过一个廉价的https/ssl证书,部署在本博客blog.path8.net上,时间大概在 2015-5-17,然而并没有正式启用,以至于过期也都没有注意。前几天想于把这个事情搞起来。以前的经验是,廉价ssl证书都是只对一个域名有效,但竟然发现Let's Encrypt的免费证书,还是多域名的。近一年的新文章里,有不少人对之大加赞扬;于是准备试试。同时也发现了腾讯云也有免费ssl证书,单域名的,免费一年,试用了一下,签发速度比较快,部署到本站上。不过还是决定使用Let's Encrypt。下面是简单记录。

CentOS + Nginx 环境下的部署

vps环境CentOS 6.x, niginx

ssh登录到服务器上操作,并且操作需要需要root权限。

1. 自动部署脚本需要epel源,如果之前没有安装先安装之 yum install epel-release

2. 在线获取签署脚本(按自己的习惯保存到合适目录)。签署脚本官方称之为客户端,有多个版本,这里使用的官方推荐的 certbot

wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

3. 运行签署脚本。脚本里注意两人参数 -w, -d,分别是一个web目录及该目录对应的域名;多组目录就多次指定。这里只是获得证书文件,不做自动部署。(猜测是因为该脚本不支持nginx的自动部署,毕竟nginx不在centos官方源里,不同服务器上安装方式 不一样)。如下所示。

./certbot-auto certonly --webroot \
-w /var/www/html/blog.path8.net/html -d blog.path8.net \
-w /var/www/html/www.path8.net/html -d www.path8.net -d path8.net -d fengyqf.com

4. 接下来会自动通过yum安装几个依赖包,同意即可。

5. 然后是几步交互式对话:邮箱地址、同意条款、照着操作即可。因为Let's Encrypt是自动签署,速度非常快,大概整个过程只花费了两三分钟(包括交互过程里等待用户操作的时间)。

letsencrypt_req_email

交互询问邮箱地址

使用国内dns服务(如dnspod)很容易引发域名解析失败,可以用 he.net 的免费解析服务。成功后消息如文后。

在目录里 /etc/letsencrypt/live/{your.domain.ext}/ 得到四个文件:cert.pem chain.pem fullchain.pem privkey.pem  。简单理解,前两个是给Apache用的,后两个是给Nginx用的。(注意 privkey.pem 这个文件是私钥,内容千万要保密!)

事实上这四个文件是到/etc/letsencrypt/archive/{your.domain.ext}/ 下文件的符号链接。从结构上看,更新证书时,会自动更新符号链接目标。

按脚本执行的输出,运行日志记录在 Saving debug log to /var/log/letsencrypt/letsencrypt.log

下面是签署脚本成功执行后的消息。

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/blog.path8.net/fullchain.pem. Your cert will
   expire on 2017-01-14. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot-auto again. To
   non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you lose your account credentials, you can recover through
   e-mails sent to f***@gmail.com.
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

6. 部署证书文件到nginx上。主要是ssl_* 的行,指定为证书路径。

    server {
        listen 80;
        listen 443 ssl;
        ssl_certificate   /{your-path-to}/fullchain.pem;
        ssl_certificate_key  /{your-path-to}/privkey.pem;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    ......
    }

7. 重新加载nginx配置 nginx -s reload  ,或者重启nginx,然后测试https访问。记得iptables放行443端口。

8. 如果需要,将http请求301重定向到https.

9. 配置定时任务以自动更新证书。重新签署证书及加载证书,将脚本加入到定时任务中,/path/to/certbot-auto renew --quiet  . 重新加载nginx配置以应用新证书的脚本如  nginx -s reload

测试ssl/https安全评级

第三方工具:https://www.ssllabs.com/ssltest/

服务器迁移至CentOS7及域名增减

2018/12/15 更新

网站服务器搬迁,从原来的centos 6升级到7,所以参考 https://certbot.eff.org/lets-encrypt/centosrhel7-nginx 的说明,centos 7下certbot安装更简单了。

yum -y install yum-utils
yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
yum install python2-certbot-nginx

迁移原服务器上/etc/letsencrypt/下几个目录到新服务器上:

/etc/letsencrypt/accounts
/etc/letsencrypt/archive
/etc/letsencrypt/csr
/etc/letsencrypt/keys
/etc/letsencrypt/live
/etc/letsencrypt/renewa

然后让nginx正常运行。修改证书关联的域名

certbot --nginx certonly --cert-name blog.path8.net -d blog.path8.net,www.path8.net,a.path8.net,...

其中 --cert-name 参数是指定证书主域名,-d 参数是修改后的域名列表

更新证书,并在更新完成后自动执行脚本。比如分发ssl证书、重加载nginx等,可以放到crontab里实现自动化

certbot renew --deploy-hook /root/script/renew_nginx_ssl.sh

 

运营方面知识点、经验等汇总

这是和篇老旧的草稿,直接发出来算了 2024/3/11


活动,有两类,基于产品的运营活动,基于市场的活动。

主题来源不同。基于市场的,来源于当前热点,根据热点事件,与当前产品找契合点,指定活动目标,玩法。

基于产品的运营,则基于当前产品,以绩效为出发点,确定活动主题、玩法、目标。

到目标的转化

用户主要分布在哪里,使用哪些产品、功能、服务,分布比例如何;哪一块最大,在运营过程中,着重满足该部分用户的需求(挖掘需求,提升体验,为用户创造价值)


运营中,目标用户在哪里,如何到达,比例如何


计算:转化率,转化

转化率,是一个比率,而转化则包含着两个不同状态(或步骤)的变化。分别以这两个状态的统计量,求比值,得转化率。首选使用同类的统计量。流量方面的两个重要统计量为PV与UV,多数时候以UV有时更合理一些。入口而的UV,一般可以通过GA获得。

转化的第二步,进入落地页。多数时候会有多个入口进入同一个落地页,这样就不容易区分每个入口带来的UV。为计算转化率,至少有两个解决方案:1)落地页加参数,如www.example.com/event/index.htm?from=entrance_1, 每个入口链接到不同的from参数。这样可以在GA中按不同的落地页创建细分,实现区分入口。2)直接使用入口链接的点击计数,求比值,虽然是不同类的统计量,但都按该方法还是有一定参考价值的。(链接计数约等于带来的PV数)。这里还有一个可选的技术细节,计数链接使用301转向并加上一定的http过期时间,比如1小时,这样,即使用户多次点击计数链接,浏览器也不重发请求。结果是,链接点击数尽量接近于UV数。

前面讲的是入口的转化及转化率。对于一个活动内容的转化,各个不同入口带来用户的转化,也可以通过不同的from参数实现,具体是使用GA细分,计算各步的UV数。

对于最后一步的成交量,为了区分不同来源的效果,也需要记录来源时(即活动落地页)的from参数。实现的技术方案:落地页增加一段程序,将from参数的值,存储到本地cookie中,注意cookie目录,正好是本活动所在目录,层级不多不少。写cookie可以使用服务器端脚本也可以通过客户端js写。

补注,这个from参数的方案很有效,可以制定成专题活动的为开发规范。


无论什么时候都要用到的原则:

  • 不重不漏。尤其是从现象中做归纳,制定规则时。场景举例:建GA细分,根据要求,制定细分条件。

完全纯粹的小白入门第一课

【几个概念】 PV,UV,会话,着陆页,退出页,跳出率,会话时长,网页标题,主机名,网址, url,javascript, js,表单,form,表格,table,像素

【直观印象】文件大小:文件大小的单位是什么,直观的认识。

图像相关:一个像素大概是什么样/电脑屏幕尺寸通常有多大/常见的图片文件格式有哪些/通常的小图片有多大

【几个问题】

网址分哪几部分,分别是什么
常见浏览器有哪些/PC操作系统有哪些/移动操作系统有哪些

凭空想象的应用中的数据加密方案

限制单用户单位时间内最大请求频次

(如每日最多请求50次内容页){仅稍微增加了采集难度,延缓被脱库时间}

对于请求频率异常的设备,封禁若干长时间(如10分钟)

技术方案参考:

  • App在请求接口时,带上设备惟一编号、当前版本号
  • 请求异常时,将设备惟一编号列入黑名单。
  • 设备惟一编号。可以使用友盟统计的 Device Token。<Tips:惟一编号方案不要与苹果的隐私规范冲突>(注意:Android可以通过清空应用数据重置该惟一编号,iOS可通过卸载后重装重置该编号)

加密数据输,请求及响应双向加密。

至少要包括:接口名,参数名,参数值。可以考虑如下加密方案:

  • 使用AES加密算法,AES密文是二进制的,最好再做一次BASE64编码。
  • 通过接口分发密钥,密钥本身也是加密传递,真实密钥需要是经过事先约定的算法计算得到。
  • 不要通过单独的接口分发密钥,而是放在其他接口中,可以放在最低允许的版本号的接口中。响应数据中,增加适量无意义的干扰信息,增加猜解难度。
  • 密钥定期修改,在服务器端更改,App启动时加密分发给App。
  • 在做协议分析时很容易猜解接口名,因此接口名可以采用另外的密钥加密,与数据传输密钥不同。可以是硬编码到App内部的固定密钥。
  • 参数名、参数值放在一起加密,即通过GET请求字符串整体加密。
  • 服务器端响应数据,也是加密后base64编码后返回密文。
  • 固定密钥不要直接出现在App的字符串资源中。

一个接口格式参考

也可以将接口地址格式改成这个形式:

host.domain.ext/interface?model=news&action=list&class=123
host.domain.ext/interface?model=news&action=detail&class=9876

将get参数加密传输后格式示例(下面只是简单的base64,没做加密)

host.domain.ext/interface?bW9kZWw9bmV3cyZhY3Rpb249bGlzdCZjbGFzcz0xMjM
host.domain.ext/interface?bW9kZWw9bmV3cyZhY3Rpb249ZGV0YWlsJmNsYXNzPTk4NzY

甚至把interface一段也重写隐藏掉,形式如

host.domain.ext/bW9kZWw9bm3cyZhY3Rpb249bGlzdCZjbGFzcz0xMjM

对于POST请求,将post包与做类似的加密封装

其它杂项

一个接口:最低允许的版本号。作用:App启动时,检查版本号,如果App版本号过低,强制用户更新。(类似网络游戏启动时检查版本补丁的方式)

如果有在线接口文档,其地址(目录命名、目录层级等)要有一定复杂度,避免被猜到。最好是授权查阅(口令、账号、IP段等)

凭空想象的web功能开发标准(性能,负载,可用性,安全,审计等多侧面)

重要数据的变动记录,及保留历史版本

对重要数据变动,做日志记录,必要的保留历史版本。可选技术方案:将所有历史版本数据存储在k-v表中,允许随时丢失部分或全部

缓存、临时文件及日志

允许这类数据存储在易失性设备上,如内存缓存。允许随时丢失部分或全部,程序不得崩溃(鲁棒性)

自己擦屁股,自动归档旧数据,尤其是存储到数据库中的旧数据,如日志表,临时文件等。至少要有相关文档,指明哪些是此类数据,如何清理,清理是否会带来后遗症(理想 状态是可以任意删除,程序本身健壮工作)

用户行为记录

uv, pv, 类似GA ,或者直接使用第三方服务

单个用户的足迹,按用户、回话划分。登陆用户的记录很自然;非登陆用户,也要有区分方案,可以类似于app中device token的实现原理。负载均衡下要按session划分。

关键步骤的记录。

分别对待:

不产生服务器上数据变更的行为,注意是浏览、搜索等行为,类似HTTP get方法的约定。选特定行为,做记录

产生服务器上数据变更的行为。无条件记录:数据产生人,时间,源IP等必要信息。数据更改及删除,还需要记录原始数据,目标:可快捷低成本的追溯历史。

 

统计类数据

统计类数据,如文章点击量,定期快照(如按月、天、小时),或者记录一定粒度(如小时,天)时间段的统计量

防范资源滥用

高资源消化的操作做qps限制

关键请求上,针对单用户限制授权额度。这里的“用户”是宽泛概念,可以是用户账号,session, ip等多种

信息分级(信息安全层面)

防止重要信息被批量采集,将这些信息分级,对不同用户级别用户展示相应部分。初级用户只能看到极少部分。

严格限制列表页:不得查询未授权的内容,防止越权读取。

信息分级(业务层面)

不同级别的信息,有差异的对待,保证信息准确性,可追溯性等。

从生命周期对信息分类,尤其是对主体信息。这里的“主体信息”,是一个模糊概念,暂时简单的理解为:在数据库里以单独表形式存储的信息,每条信息对应一条记录。划分方式相对个人化、主观化:

  • 长期有效信息:知识,规范手册,等
  • 中长有效期:,
  • 短有效期:,
  • 即时有效期:

按信息对业务重要程度划分,

  • 重要信息
  • 次重要信息
  • 不重要信息
  • ...

 

 

账号密码管理

传统的用户名密码方式,在实际使用过程中,使用人员一定会共享账号,且密码修改非常不及时。(通常是将账号密码放在文件里,如果有工作交接,直接将文件转发,或者直接在QQ里发送账号密码。因为这比“找相关人员新开设账号、设置权限”简单太多了为了。为了不影响别人使用,所以几乎都不会改密码)然而这都是重大的安全隐患。

邮箱作账号,登录后通过邮箱做验证,避免账号共享,强迫通过管理人员赋权限。企业邮箱是第三方服务,一般有较好的密码策略。

用户在同ip段登录只验证一次,若干时间内不需要重复验证。

如果多个用户在某ip段成功验证,其他人员也可以在该ip上通免验证。

超过一定时间不登录的账号,禁止登录,需要重新邮箱激活才可。

超过一定时间不使用的权限,自动撤销。这样,通常就不需要管理员取消授权。

用户管理

对用户按权限分级,如果需要的话(普通用户登录,超级用户)。权限可以查阅、发布来划分;对于管理员,则按增删改查划分。

用户状态,在登录时有相应提示,减少用户登录时提示信息异常造成的困惑,即使对已封禁用户(制定一系列状态,如:临时拒绝登录,禁言,封禁,异常锁定等)

保护用户隐私

关于请求数据

post/get之辨

请求参数格式,url简洁,事先评估是否实现rewrite兼容性

针对移动设备的http接口请求,要实现类似user-agent信息,在请求中传递,可以在http协议头中传递

功能设计原则(底线)

不希望用户操作、不希望用户看到的东西,不要列出来

必要的说明:正确,简明,有效,隐藏

不挑战用户习惯

一致性(提示文案的一致性,同类功能操作方式一致性,UI元素摆放位置一致性,etc)

功能设计原则(价值点)

有转化,可转化

有用的参考资料

  • 信息安全标准目录 http://www.cnblogs.com/merray/p/5315066.html

 

有意思的东西-GIS方面

OpenStreetMap

OpenStreetMap是一个可供自由编辑的世界地图,它是由像您这样的用户创造的。OpenStreetMap允许您查看,编辑或者使用世界各地的地理数据来帮助您。web: http://www.openstreetmap.org/

CGIAR-CSI

CGIAR-CSI, 90m精度的全球GIS数据 Free SRTM 90m Data for the entire world - FREE GIS   web: http://srtm.csi.cgiar.org/SELECTION/inputCoord.asp

Relief Map

全球地形图,还可叠加河流、道路等图层 https://maps-for-free.com/

OSGeo中国

https://www.osgeo.cn/ 国家遥感中心发起、Autodesk中国有限公司协助,经OSGeo正式授权的非营利性组织,有各种专题地图,如地理、气候、海洋、植被等等。