2019年3月

微鲸M1投影仪 使用感受

  1. 开箱
    包装是啥样的我都忘了,当时只顾看东西了. 里面主要是机器, 电源线,遥控器. 机器比以前我见过的其它投影仪都小,稍高. 据说得了IF设计大奖, 总体来说比我见过的其它正方体的投影仪都要好看. 另外它有3个接口, 分别是U盘, HDMI接口,音频输出接口, 方便播放本地视频和HDMI输入, 这可能对办公室里面的投影比较方便, 家里很少用到.
  2. 设置
    开机第一次使用设置特别特别简单, 连上电源, 打开开关, 就自动开始投影了, 关键是它会自动对焦, 并且非常快的完成自动对焦, 然后画面就呈现出来了. 唯一可能需要设置的是Wi-Fi, 选择家里的Wi-Fi, 输入密码,就没有其它需要设置的了.
  3. 体验画面
    这个是最直观的感受, 你们感受一下下面这个图片, 鸟的羽毛感觉太清晰了. 当时投影距墙大概2米, 用iphone 手机直接拍摄的画面(如果用华为最新手机拍摄, 是不是期待可以更好?). 我看说明书上说支持1670万色,如此之多. 对于常人来说还是最直接的眼睛感受的效果. 1080P的画面对于眼睛来说, 确实很舒服. 另外官网说还支持3D, 可惜我没有3D片源去试一下.
  4. 立体声
    声音效果和家里的Bose SOUNDLINK REVOLVE差不多吧, 看电影的时候, 关上门, 效果还是很不错的, 虽然比不上影院里面的几个喇叭组成的立体声效果.
  5. 视频内容
    首先它自带了自家的各种视频频道, 电影,电视剧, 综艺, 动漫, 儿童动画, 新闻啥都有. 另外它就像一个电视盒子, 也就是说你可以安装任意第三方的视频APP, 比如爱奇艺, 腾讯视频, 优酷, PPTV, 央视视频等. 因为我有爱奇艺的会员, 就装了一个爱奇艺的app. 它自带的app商店如果没有某些app, 可以通过电脑下载到U盘, 然后插入U盘, 选择本地文件安装就可以.
  6. 儿童动画
    这个呢, 要单独说一下, 里面自带的视频里面专门有儿童视频资源, 儿子最喜欢的小猪佩奇既有中文版, 还有英文版, 各种其它动画也都有. 另外还有家长控制的儿童锁, 可以限制小孩看的时间. 晚上很晚之后, 如果在打开动画, 会有专门的提示告诉你太晚了.
  7. 投屏
    如果它和手机在同一个Wi-Fi, 那么不管是iphone, 还是安卓手机, 都可以直接投. 投影仪里面有个详细介绍怎么投的, 非常好用. 更神奇的是, 如果没有Wi-Fi, 它竟然也可以投, 它会自己建立一个Wi-Fi热点, 你手机连上去, 就可以投屏了! 看到有人说它还可以异地投屏! 不知道这是什么更神奇的功能.
  8. 智能音箱
    它还可以当作音箱来用, 这个时候,它会熄灭屏幕, 如果你没有通过蓝牙连接它, 它会自动选择歌曲播放, 当然你也可以语音控制播放. 如果它正在投影,突然有手机连上它的蓝牙, 它也会问你要不要当音箱用, 还是继续投影. 手机蓝牙连接之后, 它就是一个手机控制播放的音箱了.
  9. 其它
    历史记录功能, 之前看了啥, 上次看到哪里了, 这次接着看; 开关机有短暂广告,貌似无法去掉; 它还可以语音交互, 这个挺方便; 没有播放声音的情况下, 能听到机器的声音, 播放声音之后, 基本就听不到机器运行的声音了.

总体来说, 非常值.
============== 有关其它问题 ===========

  1. 支持USB播放吗?
    有个USB接口, 插入USB后, 找到播放本地文件, 除了能看到机器自带的盘, 另外的盘就是插入的U盘. 其实我没有使用U盘播放电影, 不过我用电脑下载一个爱奇艺电视app, 通过U盘拷贝进去, 点击安装该app.
  2. USB 能带动移动硬盘吗?
    虽然我有移动硬盘, 不过没有试过, 它的输入电源类似dell笔记本电脑, 我想应该可以带动.
  3. 连不上网 Wi-Fi?
    恢复出厂设置, 再连就可以了.

java 启动参数 -XX:+PrintHeapAtGC

在启动时, 加入 -XX:+PrintHeapAtGC 将会看到如下log 打印

{Heap before GC invocations=4 (full 0):
 PSYoungGen      total 17408K, used 17392K [0x00000000fdf00000, 0x0000000100000000, 0x0000000100000000)
  eden space 16384K, 100% used [0x00000000fdf00000,0x00000000fef00000,0x00000000fef00000)
  from space 1024K, 98% used [0x00000000fef00000,0x00000000feffc010,0x00000000ff000000)
  to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
 ParOldGen       total 68608K, used 34096K [0x00000000f9c00000, 0x00000000fdf00000, 0x00000000fdf00000)
  object space 68608K, 49% used [0x00000000f9c00000,0x00000000fbd4c000,0x00000000fdf00000)
 Metaspace       used 2612K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 285K, capacity 386K, committed 512K, reserved 1048576K

[GC (Allocation Failure) [PSYoungGen: 17392K->1024K(32768K)] 51488K->52816K(101376K), 0.0101398 secs] [Times: user=0.00 sys=0.00, real=0.00

Heap after GC invocations=4 (full 0):
 PSYoungGen      total 32768K, used 1024K [0x00000000fdf00000, 0x0000000100000000, 0x0000000100000000)
  eden space 31744K, 0% used [0x00000000fdf00000,0x00000000fdf00000,0x00000000ffe00000)
  from space 1024K, 100% used [0x00000000fff00000,0x0000000100000000,0x0000000100000000)
  to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
 ParOldGen       total 68608K, used 51792K [0x00000000f9c00000, 0x00000000fdf00000, 0x00000000fdf00000)
  object space 68608K, 75% used [0x00000000f9c00000,0x00000000fce94050,0x00000000fdf00000)
 Metaspace       used 2612K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 285K, capacity 386K, committed 512K, reserved 1048576K
}

参考:
https://blogs.oracle.com/poonam/how-do-i-find-whats-getting-promoted-to-my-old-generation/comment-submitted?cid=216c187b-792f-487b-843b-a326449b7120

Java GC 之 CMS 的一些 trade off

  1. 若young gen 过小, 则会频繁发生young GC, gc overhead 过高, 同时大量premature对象被promote到 old gen, 同时old gen 可能会引起大量碎片, 最终引起碎片化;
  2. -XX:PrintFLSStatistics=1 打印free list in BinaryTreeDictionary. 如果=2, 则会花费更多时间打印更多信息.

参考:
https://blogs.oracle.com/poonam/can-young-generation-size-impact-the-application-response-times

Java 程序中导致CPU 100%的常见原因与诊断思路

上周某团队的某个业务的新功能1%上线, 上线不到1天, 开发人员发现该流程里下游有个应用不断有服务器挂掉, 症状表现为CPU 100%, 不能处理新请求. 为了临时快速解决该问题, 同事先是做了2个 heap dump 和 2个 CPU 在某个interval的usage的截屏, 然后让开发人员关闭该新功能, 同时下游服务器被完全重启一遍. 问题得以解决.

问题虽然被临时解决, 但是当时却没发现最终问题所在. 事后去查看相关log, 发现某些机器竟然在那个时间段, 没有把log发到中心log 服务器, 同时本地的某些log被覆盖. 根据截屏的 CPU usage, 发现有很多线程在当时在cache中查找某些值, 有几个线程在HashMap中get()某个值, 看上去很像HashMap的死循环问题, 可是另外有些花费很多CPU的线程又没在HashMap里面. 不过最终查看这些线程Stack, 确定问题是业务逻辑里面有如下代码:

TreeNode curNode = curNode.getParentNode();
Integer curVal = null;
while (null != curNode && null == curVal) {
    curVal = getSomeValueFromConfigCache(curNode);
}

仔细一看, 上面的代码是有问题的, 看上去哪些Node 是一个Tree 结构, 如果通过当前Node 查不到,就根据Parent去查, 结果这个逻辑里面并没有把向上替换的逻辑放到 while 循环里面. 根据当前的代码, 如果当前Node 查不到返回null, 那么这个while 就是一个死循环了. 所以改正很简单, 但是这个代价有点大. 测试代码可能99%都是当前Node 都能查到结果的, 可是就是有1%的数据, 可能要向上找到 ParentNode 才能查到.

对于这种导致CPU 100%的问题, 我们常见的有以下这几种:

  1. Java 内存不够或溢出导致GC overhead问题, GC overhead 导致的CPU 100%问题;
  2. 死循环问题. 如常见的HashMap被多个线程并发使用导致的死循环, 或者上面例子中的死循环;
  3. 某些特费CPU的操作被长期执行. 以前有个case, 使用正则表达式去判断是不是符合某个规则, 可是有些时候输入参数是一个几十K或更长的数据, 该正则写又不好, 导致CPU遇到这种输入, 就爆掉了.
  4. 频繁的获取/释放锁 大量的锁操作 比如大量线程快速同步写 log 到 System.out/System.err (PrintStream).
  5. 频繁获取线程的 Stacktrace. 比如为了 profiling 频繁获取, 出错写 e.printStacktrace() 等操作.
  6. 很多线程都在忙于 压缩/解压缩 操作

对于上面第一种类型, 基本可以通过GC overhead 的比例去看, 这种情况下CPU完全是GC 引起的, GC overhead 基本接近100%, 然后下一步就是做 heap dump, 去分析verbose GC log 和 heap dump;

对于上面第二种, 可以多次做CPU usage分析, 比如每次都是1s的interval 内所有线程消耗CPU的百分比, 因为CPU 已经100%, 所以很容易可以看到是哪些线程在大量消耗CPU, 然后去分析这些stacktrace, 基本上死循环的代码之外的stack每次都一样, 死循环以内的某些时候的stack有些差别. 可以通过结合 heap dump 里面的局部变量, 参数同时阅读stack里面的方法的调用关系, 去查看死循环的位置所在. 对于HashMap这种, 基本在几次tread dump中就能确定, 然后去 heap dump 去找到那个循环.

对于第三种, 基本和第二种一样, 首先观察下stack里面有没有看上去就是特耗CPU的操作, 如果有继续看源代码去查看. 最后结合heap dump里面的数据去验证.

对于第四种, 多次查看 thread dump, 就会发现频繁获取释放的锁.

对于第五种, 多次查看 thread dump, 有可能会看到, 或者看到特别多的出错写 log 的.

OpenSSL 基本知识

  1. 目的/作用? PKI的一部分
  2. 实现架构/组件/组成 key, cert, CA, CA chain
  3. OpenSSL 包含 cryptographic library and an SSL/TLS toolkit;
  4. 一个 SSL/ TLS的实现, 一个de facto standard;
  5. Privacy-Enhanced Mail (PEM) format;
  6. 背景: 开源 广泛使用 高性能;
  7. 带命令行工具 方便调试
$ openssl version
OpenSSL 1.0.2g  1 Mar 2016
$ openssl version -a
OpenSSL 1.0.2g  1 Mar 2016
built on: reproducible build, date unspecified
platform: debian-amd64
options:  bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)
compiler: cc -I. -I.. -I../include  -fPIC -DOPENSSL_PIC ... -DECP_NISTZ256_ASM
**OPENSSLDIR: "/usr/lib/ssl"**
$ls /usr/lib/ssl -la  //配置文件路径
lrwxrwxrwx  1 root root   14 Jun 20  2018 certs -> /etc/ssl/certs
drwxr-xr-x  2 root root 4096 Jan 10 10:55 misc  //各种工具脚本
lrwxrwxrwx  1 root root   20 Dec  4 13:07 openssl.cnf -> /etc/ssl/openssl.cnf
lrwxrwxrwx  1 root root   16 Jun 20  2018 private -> /etc/ssl/private

 $openssl help

$man ciphers
$ openssl genrsa -aes128 -out fd.key 2048 //生成key 文件
$ openssl rsa -text -in fd.key //读取key 文件
$ openssl rsa -in fd.key -pubout -out fd-public.key //通过private key 生成public key;

$openssl s_client -showcerts  -connect www.ebay.com:443
$openssl s_client -debug  -connect www.ebay.com:443