怎么找出服务器流量多的接口?

一、问题

最近发现服务器流量增加一倍,因为后台开发没有加日志,无法分析流量的走向,就算有日志,也无法很好发现流量的占比。

二、解决过程

  1. tcpdump 抓包,保存文件(如果windows直接用wireshark抓包即可)
  2. 用wireshark 统计模块,可以看各个接口占比和流量速度

三、缺点

因为https 证书问题,直接抓包无法解密HTTPS,但自己服务器,应该可以解密,这个百度一下wireshark 解密HTTPS 配置 应该就可以了。

mysql 拿取随机数据思考

一、背景

自己因为有一个答题插件逻辑,需要从数据库随机选择一定数目的题目,这个业务已经被同事实现,但我觉得他实现不对或者不够好,于是思考这个问题。他用rand() 产生一个随机数,然后大于这个随机数 加上limit 得到 题库。

二、问题

  1. 题库是连续的,用户体验不好
  2. 随机概率增大,如果用这个思路写抽奖那么绝对是不对的。

三、解决思路

假设我们选择uid 用户的ID 是整数,主键。。

select * from xxx where uid >= (rand(max(uid) – min(uid) ) + min(uid)) limit 1

上面手写,不代表语法正确, rand 只是找一个随机数据, 这个可以程序传过来,不一定要数据库随机数。 后面+min(uid) 只是为了防止随机到0而已,保证uid最小值而已。

如果要随机多条,应该调用多次,而不是limit 10 (假设多条是10),因为这里有一个隐藏前提,随机条数和数据必须差别比较大,不然很可能出现连续,而不是看起来随机的。

四、补充

select * from xxx where uid >= (rand(max(uid) – min(uid) ) + min(uid)) limit 1

select * 加了条件,如果数据库有10条数据,uid(0~9),如果我随机5条数据话,如果用上面的 select * from xxx where uid >= (rand(max(uid) – min(uid) ) + min(uid)) limit 5 。很容易出现连续的,而且数据缺失。select * 拿数据,会一行行拿,条件对比,而不是扑通一下拿取所有数据,然后才进行对比,所以用rand() limit 个数,会出现不连续,而你自己用 select * from xxx where uid >= 10 limit 5 却是 连续的,这里10我只是随便举一个数字而已。 如果数据少,加上UID自增,随机到大于5是50% ,如果我选择5条数据,那么很容易不够,并且连续,这里连续满足where条件太少了,所以导致连续,如果数据足够多就没有这个问题。

我以前全表扫描比较慢,测试200W数据,个人电脑也就0.85秒消耗。如果加上条件那么速度快很多,更不要说有索引的情况下。。。

这个问题我记录下来,只是跟后端开发探讨出来,自己不喜欢写数据库东西。只是记录技术而已。

大小端理解

一、背景

这块知识点算是比较常见,我们传送网络二进制自定义协议一定会遇到的,我最近看到一个问题,于是我思考为什么会有大小端的问题,他到底是哪一层导致的。基本知识我这里就不说了,自己搜索一下就能知道

二、思考

我们看的书籍或者网络的文章都说大小端跟CPU有关系,但跟高级语言没有关系,我们用c/c++,c#的时候我们赋值给变量根本不关心大小端,比喻 short i = 0x1234 我们根本不用关心他在内存里面是大端还是小端,因为他的值就是0x1234。不用关心他的内存形式。

另外一个知识点,i = a + b; 如果a 和 b 如果在别的线程可能被修改,那么这样行代码是非线程安全的,那为什么会线程不安全, 因为 i = a + b 在汇编层是多行代码,并不是一行代码,所以高级语言的线程安全,不能只看高级语言层线程安全,单行操作代码也可能是非线程安全的。【这里举例不是非常好,如果以后能想到更合适才写吧】

我们知道cpu 没有变量概念,只认识0 和 1 ,高级语言不关心内存的形态,那么可以断定大小端只是汇编层问题,我们知道汇编 命令 + 操作数, 那么32 位中 操作可以word 也可以是dword ,汇编是跟cpu最直接的,所以厂商不一样,操作数在内存形式不一样,所以才出现大小端的问题。所以问题是在汇编层导致。

三、补充

自己google了一下也没有找到任何英文文档来证明我上概念。

java后端部署不同系统后出现乱码

一,背景

项目从windows部署到centos,在客户端获取数据出现中文乱码,自己百度半天,各种编码设置也没有解决问题。

二,排查

根据上下文推测,应该跟系统的编码有问题,因为windows 默认编码gdk,然后centos默认编码是utf-8。所以猜测代码里面涉及系统默认编码问题,于是猜测 String getbytes(),如果改成getbytes(“utf-8”)就没有乱码了。

三,总结

乱码问题,基本都是服务器和客户端编码对不上导致的问题

过期Map自己逻辑实现

背景

一个接口A会请求另外一个接口Btoken是否有效【因为2个服务器,token存放在 接口B redis里面】,为了减少接口A请求B的次数,我们希望在A实现一个简单的过期Map。

逻辑

  • 用对应的语言的map
  • 创建定时器随机抽取一些值做是否过期校验【确保线程问题,因为我们用Node 全部都在主线程,所以没有竞争,其他语言可以通过任务队列来保证线程竞争,建议不要加锁】
  • 获取key校验是否过期,然后再验证是否有效

总结

上述思路借鉴redis过期逻辑,保证cpu消耗和内存占用,一种比较好的策略。同事开始希望用redis实现,我的意见是在保证完成工作前提前,采用新的技术,而不是用一个技术用到老,不然就变成搬砖了。

后端开发之token 常见逻辑

背景

我最近正好遇到这样子的需求,自己跟同事讨论一下,得出了一些结论,于是我就写下来方便其他遇到类似的问题。

需求

用户访问一个url,然后这个Url会调到公众号得到用户授权,然后获取openid,然后跳转到最终的展示页面。同事开发时候直接跳转了最终的展示页面,同时带了openid,却没有其他验证,我开始跑流程时候没有注意到这个逻辑,后面突然发现,你既然没有带任何验证,openid 又是固定,那么用户只要复制这最终的url,那么他后面就不需要任何授权。所以这个就一个非常巨大的安全问题。

解决方案

公众号回调接口时候,我们继续回调自己业务层,业务层生成token,返回对应最后落地页。

补充

跳转到落地页时候是一个接口,判断token是否有效,然后再生成cookie,设置过去。注意set-cookie 是不能夸域名的,我们最开始写cookie放在公众号回调里面,没有在对应的业务层的回调。开始因为可以302时候设置到跳转的域名里面,后面测试不可以,通过逻辑分析确实就不应该设置。

场景

  • 公众号登陆,跳转到最终落地页
  • 客户端已经登陆,跳转浏览器
  • 第三方登陆,qq或者微信,原理类似