0%

Redis Lua脚本的几种应用场景

批量删除符合某种pattern的keys

bin/redis-cli eval “return redis.call(“del”,unpack(redis.call(“keys”,ARGV[1])))” 0 “HelloWorld*”
该命令会删除所有以HelloWorld开头的keys。

迁移db index的lua脚本

1
2
3
4
5
6
7
8
local result={};

local keys =redis.call("keys","*");

for i = 1, #keys do
local val= redis.call("move", keys[i], 0);
end
return result;

以上也是很常见的一种脚本范式,先根据需要查询获取到所有的key,再遍历这些key进行想要的操作,例如move, del, rename等等。

NVM安装新版本node之后的 global packages 迁移

NVM安装新版本node之后,全局的package需要迁移,注意使用以下命令,这样就不用手动一个个安装global package了。
例如我今天安装了v8.12.0的node,之前的版本是v8.11.3,那么执行以下命令就可以了。

1
2
3
4
nvm install v8.12.0
nvm reinstall-packages v8.11.3 # 把在v8.11.3版本node下安装的全部global package安装到新的node下面
nvm uninstall v8.11.3
nvm install-latest-npm # 顺便更新一下npm
阅读全文 »

在前端与后端交互的过程中,很可能会遇到使用RSA公钥加密,然后用私钥解密的情况,
RSA的私钥签名,公钥验签同样也很常用,这里简单介绍一下 JavaScript 语言RSA算法的一些解决方案。

NodeJs环境

可以直接引入NodeJs自带的crypto模块,基于RSA/ECB/PKCS1Padding加密,用法如下:

1
2
3
4
5
6
const crypto = require('crypto');
private RSAEncrypt(rsakey:string, text:string){
let encrypted = crypto.publicEncrypt({key:rsakey,
padding:crypto.constants.RSA_PKCS1_PADDING},new Buffer(text)).toString('base64');
return encrypted;
}

其中rsakey为pem格式的公钥,可以从文件读取,或者指定字符串,字符串格式如下:

1
rsakey='-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCm5IN1uRvak0Kod3YviD/b67dj\nzP/ubU+8RgbCnm1HUVYBAVGnvg5epMfGunXKFXSb1ehOvQ2K+fEJLa+pKy2uLZLd\n/6gbUGJn+q8wGiFKfu0U0H3E+2yH6eFX+IPXx5OJNwUE6yqKR6hOBz5qR/AtVRfM\n6aAcDLIR7wE06SnHVQIDAQAB\n-----END PUBLIC KEY-----\n'

text就是准备加密的字符串了,直接调用该方法就可以完成加密过程。

参考:https://nodejs.org/docs/latest-v8.x/api/crypto.html#crypto_crypto_publicencrypt_key_buffer

JavaScript native or a web browser

如果是单纯的浏览器环境,推荐forge.js
代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!doctype html>
<html>
<head>
<title>JavaScript RSA Encryption</title>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/node-forge@0.7.0/dist/forge.min.js"></script>
<script type="text/javascript">

// Call this code when the page is done loading.
$(function() {

// Run a quick encryption/decryption when they click.
$('#testme').click(function() {

var publicKey = forge.pki.publicKeyFromPem($('#pubkey').val());

// convert string to UTF-8 encoded bytes
var buffer = forge.util.createBuffer($('#input').val());
var bytes = buffer.getBytes();

// encrypt data with a public key using RSAES PKCS#1 v1.5
var encrypted = publicKey.encrypt(bytes, 'RSAES-PKCS1-V1_5');

// base64-encode encrypted data to send to server
var b64Encoded = forge.util.encode64(encrypted);
console.log(b64Encoded);
alert(b64Encoded);
});
});
</script>
</head>
<body>
<label for="pubkey">Public Key</label><br/>
<textarea id="pubkey" rows="15" cols="65">-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDY08fkt9d32KHV1JapaZGtk+fL
a7wvxMAdZ0oENhx6HgBisSlDwCgBfRtN5l2iOjKm+eByp7Od24JqIOwgDF6FZ/ol
CQbnXjzPhG0EOeLnu3AXntzhu9A0yS7b3p+pxGR7EvhIz1xkOS4bNABsAgF7Y5Zu
B1RpsOZZdxNHGeStBwIDAQAB
-----END PUBLIC KEY-----</textarea><br/>
<label for="input">Text to encrypt:</label><br/>
<textarea id="input" name="input" type="text" rows=4 cols=70>Hello World!</textarea><br/>
<input id="testme" type="button" value="RSA Encrypt" /><br/>
</body>
</html>

参考:

阅读全文 »

概念

CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart,简称CAPTCHA),俗称验证码,是一种区分用户是计算机或人的公共全自动程序。在CAPTCHA测试中,作为服务器的计算机会自动生成一个问题由用户来解答。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答CAPTCHA的问题,所以回答出问题的用户就可以被认为是人类。

目前验证码被广泛应用于网站登录、注册、防刷等处,用于识别和防止自动化程序恶意获取服务和数据。

类型

目前大家常见的几类验证码有:

  • 标准验证码(图片),图片中一般是随机组合的字母和数字,对背景和内容进行扭曲,增加噪点和曲线,使程序难以识别
  • 根据界面图形,进行鼠标、手指(移动端)交互操作(滑动拼图验证,点选验证)
  • No CAPTCHA (Google新一代reCAPTCHA,升级的风险分析技术可以智能无感知的判断人类与机器)
  • 语音验证(播放一段音频给用户,用户获取信息后提交比对)
  • 短信、邮箱验证
    阅读全文 »

Sample Dockerfile

后面的讲解,以该Dockerfile构建的镜像为例说明。

1
2
3
4
5
6
7
FROM openjdk:8-jre-alpine

MAINTAINER leimingshan

ADD xxl-sso-server-0.1.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

xxl-sso-server-0.1.1-SNAPSHOT.jar是Spring Boot打包生成的可执行jar,内嵌tomcat容器,直接使用java -jar启动内嵌
的tomcat容器并监听8080端口,这里是最简单的一种制作Spring Boot程序镜像的方法,java -jar就是容器内的主进程,如果该
进程终止,容器也就相应退出。

另外一种常见的镜像制作方法,就是加入supervisor来管理进程,稍微重一些,适合管理容器内的多个进程,此时,java等进程是supervisord的子进程,Dockerfile中的命令也要变成

1
ENTRYPOINT ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"] 

supervisord也是容器内的进程命令,只要supervisord不退出,容器就不会退出。

Spring Boot相关的内容大家可以自行学习下,这里就不详述了。

Detached vs foreground

Docker run命令运行一个容器的时候,有一个-d选项

-d=false: Detached mode: Run container in the background, print new container id

detached的意思是让容器在后台运行,同时与你当前终端的STDIN,STDOUT,STDERR分离,然后告诉你一个容器id。
执行该命令之后,我们只会看到一个容器id。

默认不指定-d选项的时候,即-d=false,容器在前台运行,此时容器
处于attached状态,或者说是foreground前台模式,容器内进程(一般是ENTRYPOINT指定的运行命令)的STDIN,STDOUT,STDERR
会与你当前的命令行终端连接,你就可以直接看到容器内进程执行时候的输出,而你的输入也会重定向到容器内进程。以示例镜像运行产生的容器来说,你的所有输入输出都是和java -jar进程关联的。

参考:https://docs.docker.com/engine/reference/run/#detached-vs-foreground

阅读全文 »

历史

sun.misc.Unsafe至少从2004年Java1.4开始就存在于Java中了。
在Java9发布之前,有传闻说Oracle会在Java9正式发布时移除sun.misc.Unsafe,引起了激烈的争论。
因为有不少重要的Java开发库都在底层使用了sum.misc.Unsafe,例如Netty,Neo4J,Spring Framework,Apache Kafka,Apache Storm等。
新的替代API成熟之前,直接移除Unsafe是很冒险的一项做法。

JEP 260是Java9中一项重要内容,意在封装那些JDK内部使用的API,而不再提供给外部应用使用。
鉴于类似Unsafe这类非常关键而广泛使用的API,目前也没有非常有效的替代方案,暂时得到了保留,因此在JDK9中,我们仍然可以使用Unsafe类,目前没有被内部封装。
在JDK9中jdk.internal.misc中也可以找到Unsafe类。

JDK9中没有被封装的关键内部类有:

  • sun.misc.{Signal,SignalHandler}
  • sun.misc.Unsafe (许多功能可以通过variable handles实现,后面介绍)
  • sun.reflect.ReflectionFactory
  • com.sun.nio.file.{ExtendedCopyOption,ExtendedOpenOption, ExtendedWatchEventModifier,SensitivityWatchEventModifier}

这些类在以后的版本中可能被移除或封装。而非关键类例如sun.misc.BASE64Encoder和sun.misc.BASE64Decoder则直接被移除了。

阅读全文 »

正式发布

9月25日,Oracle官方宣布Java11(18.9 LTS)正式发布,可在生产环境中使用!
Java11是Oracle在2017年宣布新的JDK发布时间表之后,第一个长期支持 - Long Term Support(LTS)版本,非常值得大家关注。
如果说之前的Java9和Java10关注度都比较小,基本都被大家忽略的话,Java11可是绝对不容错过的。
作为新版发布路线的第一个LTS版本,其重要性和对后面版本的影响都不言而喻,
Oracle直到2023年9月都会为Java 11提供技术支持,而补丁和安全警告等扩展支持将持续到2026年。
LTS版本每三年发布一次,根据后续的发布计划,下一个LTS版本,应该是Java17,要在3年后的2021年才会与大家见面。

为了更快地迭代,以及跟进社区反馈,自2018年起,Java的版本发布周期变更为每六个月一次 —— 每半年发布一个大版本,每个季度发布一个中间特性版本,并且承诺不会跳票。
通过这样的方式,开发团队可以把一些关键特性尽早合并到JDK之中,以快速得到开发者反馈,在一定程度上避免出现像Java 9这样两次被迫延迟发布的窘况。

按照官方的说法,新的发布周期会严格遵循时间点,将于每年的3月份和9月份发布。所以Java 11的版本号是18.9(LTS)。

不过与Java 9和Java 10这两个被称为“功能性版本”不同(两者均只提供半年的技术支持),Java 11不仅提供了长期支持服务,还将作为Java平台的参考实现,并技术支持到2023年9月。

阅读全文 »

两年前比较早的时候,git刚流行起来,私服方案记得只有一个,就是gitlab,gitlab自己提供累死github的公有服务器,也提供自己搭建
服务的功能,现在官方还有了docker image,可以说是非常方便了。

Gitlab的特点:

  • 优点:功能很全,自带CI持续集成和Issue tracking。
  • 缺点:比较重,配置要求高。建议独立部署,内存需求比较大。

最近偶尔看到了几个非常轻量的自建git服务,这里简单记录一下,以后也许会用得到:

  1. Gogs。https://gogs.io/。GO语言开发,跨平台,支持docker。
  2. Gitea。Gogs的社区开发维护版本。https://gitea.io/zh-cn/。

静态代码压缩

因为Blog中都是静态页面,基本都可以压缩优化,针对html,css,js,图片进行。
这里没必要用gulp去压缩,配置太繁琐,也没法自动化。
直接使用hexo-all-minifier这个模块,
安装:

npm install hexo-all-minifier –save

增加配置:

all_minifier: true

搞定!

文章唯一链接

hexo-abbrlink

文章字数统计和阅读时长

hexo-symbols-count-time
可以替代老的hexo-wordcount。

SEO-搜索引擎收录和优化

利用插件生成sitemap,hexo自带的两个插件,百度搜索要使用单独的一个。

阅读全文 »

JDK 11即将于09/25正式发布,包含了诸多新的特性,主要的新特性JEP(JDK Enhancement Proposal 特性增强提议)有17个,参见下表

  • 181: Nest-Based Access Control
  • 309: Dynamic Class-File Constants
  • 315: Improve Aarch64 Intrinsics
  • 318: Epsilon: A No-Op Garbage Collector
  • 320: Remove the Java EE and CORBA Modules
  • 321: HTTP Client (Standard)
  • 323: Local-Variable Syntax for Lambda Parameters
  • 324: Key Agreement with Curve25519 and Curve448
  • 327: Unicode 10
  • 328: Flight Recorder
  • 329: ChaCha20 and Poly1305 Cryptographic Algorithms
  • 330: Launch Single-File Source-Code Programs
  • 331: Low-Overhead Heap Profiling
  • 332: Transport Layer Security (TLS) 1.3
  • 333: ZGC: A Scalable Low-Latency Garbage Collector(Experimental)
  • 335: Deprecate the Nashorn JavaScript Engine
  • 336: Deprecate the Pack200 Tools and API

其中,非常值得大家关注的是JEP-333,ZGC,一个可扩展的低延迟垃圾回收器。ZGC目前仍处于实验阶段,不建议在生产环境使用。
目前使用ZGC需要添加JVM参数:-XX:+UnlockExperimentalVMOptions -XX:+UseZGC

阅读全文 »