1.Jvm-Sandbox原理分析-Sandbox的源码启动-01
2.springboot如何进行混淆加密(proguard+xjar)
3.XJar(防源码泄漏)使用指南
4.万字长文入门Vert.x
Jvm-Sandbox原理分析-Sandbox的启动-01
Jvm-Sandbox的启动(一):sandbox.sh脚本分析
Sandbox的启动是通过其内置的shell脚本 sandbox.sh 开始执行的,一切的解析开始皆可从该脚本中探寻出结果。脚本有一定的源码代码量,大概有+行,解析这里将该脚本分为如下几个部分进行讲解:
1、源码变量定义过程这个过程首先预定义了接下来即将使用的解析课本网站源码一些变量。代码如下:
# 定义sandbox的源码home目录,并为其赋值 typeset SANDBOX_HOME_DIR [[ -z ${ SANDBOX_HOME_DIR} ]] && SANDBOX_HOME_DIR=${ PWD}/..# 定义 SANDBOX_USER,解析并为其赋值 typeset SANDBOX_USER=${ USER} [[ -z ${ SANDBOX_USER} ]] && SANDBOX_USER=$(whoami)# 定义 SANDBOX_SERVER_NETWORK typeset SANDBOX_SERVER_NETWORK# 定义lib目录,源码这个目录下主要存放jar包 typeset SANDBOX_LIB_DIR=${ SANDBOX_HOME_DIR}/lib# 定义 SANDBOX_TOKEN_FILE typeset SANDBOX_TOKEN_FILE="${ HOME}/.sandbox.token"# 定义JVM参数 SANDBOX_JVM_OPS typeset SANDBOX_JVM_OPS="-XmsM -XmxM -Xnoclassgc -ea"# 定义目标JVM的解析进程号,后面的源码agent主要attach到该JVM进程上 typeset TARGET_JVM_PID# 定义目标机器IP以及默认机器IP typeset TARGET_SERVER_IP typeset DEFAULT_TARGET_SERVER_IP="0.0.0.0"# 定义目标进程端口 typeset TARGET_SERVER_PORT# 定义名称空间 typeset TARGET_NAMESPACE typeset DEFAULT_NAMESPACE="default"注释和变量命名已经描绘的非常清楚了,在看后面代码遇到忘记了的解析变量可以到这里来回顾下。
这里为其中一些变量补充说明:
SANDBOX_HOME_DIR:shell脚本中,源码-z表示检测紧跟的解析字符串长度是否为0,如果为0返回true。源码这里使用短路与,如果 ${ SANDBOX_HOME_DIR} 为0,则使用 ${ PWD}/.. 的目录作为sandbox的home目录。这种方式表示优先使用环境变量 SANDBOX_HOME_DIR,易语言 工控源码如果未定义环境变量SANDBOX_HOME_DIR,则使用当前目录。
SANDBOX_TOKEN_FILE:这个文件主要存放了sandbox attach记录,包括attach进程的host:port。
TARGET_SERVER_IP:一般情况下,我们都是将整个工程打包后上传至目标机器,然后在目标机器上执行该shell脚本,因此默认机器IP一般为localhost即可。
2、执行入口执行入口就比较简单了,就一行代码,其中${ @}会保存我们传递给该shell脚本的所有参数:
main "${ @}"比方说,我们以如下命令启动脚本,则${ @} 就包含了-p 这个参数
./sandbox.sh -p 、main函数main函数是该脚本的重要方法,也是脚本的执行入口,它主要完成了以下几件事:
其代码如下所示:
function main() { # 遍历脚本参数 while getopts "hp:vFfRu:a:A:d:m:I:P:ClSn:X" ARG; do case ${ ARG} in h) # 帮助手册函数,大家可以自行翻阅源码查看 usage exit ;; # 赋值PID p) TARGET_JVM_PID=${ OPTARG} ;; v) OP_VERSION=1 ;; l) OP_MODULE_LIST=1 ;; R) OP_MODULE_RESET=1 ;; F) OP_MODULE_FORCE_FLUSH=1 ;; f) OP_MODULE_FLUSH=1 ;; u) OP_MODULE_UNLOAD=1 ARG_MODULE_UNLOAD=${ OPTARG} ;; a) OP_MODULE_ACTIVE=1 ARG_MODULE_ACTIVE=${ OPTARG} ;; A) OP_MODULE_FROZEN=1 ARG_MODULE_FROZEN=${ OPTARG} ;; d) OP_DEBUG=1 ARG_DEBUG=${ OPTARG} ;; m) OP_MODULE_DETAIL=1 ARG_MODULE_DETAIL=${ OPTARG} ;; # 赋值IP I) TARGET_SERVER_IP=${ OPTARG} ;; # 赋值PORT P) TARGET_SERVER_PORT=${ OPTARG} ;; C) OP_CONNECT_ONLY=1 ;; S) OP_SHUTDOWN=1 ;; n) OP_NAMESPACE=1 ARG_NAMESPACE=${ OPTARG} ;; X) set -x ;; ?场地预约 php源码) usage exit_on_err 1 ;; esac done # 重置环境 reset_for_env # 校验权限 check_permission# 根据不同的参数,进行相应处理 # 如果没有指定IP,则使用默认值 [ -z "${ TARGET_SERVER_IP}" ] && TARGET_SERVER_IP="${ DEFAULT_TARGET_SERVER_IP}"# 如果没有指定port,使用默认值 [ -z "${ TARGET_SERVER_PORT}" ] && TARGET_SERVER_PORT=0# reset NAMESPACE [[ ${ OP_NAMESPACE} ]] && TARGET_NAMESPACE=${ ARG_NAMESPACE} [[ -z ${ TARGET_NAMESPACE} ]] && TARGET_NAMESPACE=${ DEFAULT_NAMESPACE}if [[ ${ OP_CONNECT_ONLY} ]]; then [[ 0 -eq ${ TARGET_SERVER_PORT} ]] && exit_on_err 1 "server appoint PORT (-P) was missing" SANDBOX_SERVER_NETWORK="${ TARGET_SERVER_IP};${ TARGET_SERVER_PORT}" else # -p was missing [[ -z ${ TARGET_JVM_PID} ]] && exit_on_err 1 "PID (-p) was missing." # attach jvm的核心方法 attach_jvm fi# -v show version [[ -n ${ OP_VERSION} ]] && sandbox_curl_with_exit "sandbox-info/version"# -l list loaded modules [[ -n ${ OP_MODULE_LIST} ]] && sandbox_curl_with_exit "sandbox-module-mgr/list"# -F force flush module [[ -n ${ OP_MODULE_FORCE_FLUSH} ]] && sandbox_curl_with_exit "sandbox-module-mgr/flush" "&force=true"# -f flush module [[ -n ${ OP_MODULE_FLUSH} ]] && sandbox_curl_with_exit "sandbox-module-mgr/flush" "&force=false"# -R reset sandbox [[ -n ${ OP_MODULE_RESET} ]] && sandbox_curl_with_exit "sandbox-module-mgr/reset"# -u unload module [[ -n ${ OP_MODULE_UNLOAD} ]] && sandbox_curl_with_exit "sandbox-module-mgr/unload" "&action=unload&ids=${ ARG_MODULE_UNLOAD}"# -a active module [[ -n ${ OP_MODULE_ACTIVE} ]] && sandbox_curl_with_exit "sandbox-module-mgr/active" "&ids=${ ARG_MODULE_ACTIVE}"# -A frozen module [[ -n ${ OP_MODULE_FROZEN} ]] && sandbox_curl_with_exit "sandbox-module-mgr/frozen" "&ids=${ ARG_MODULE_FROZEN}"# -m module detail [[ -n ${ OP_MODULE_DETAIL} ]] && sandbox_curl_with_exit "sandbox-module-mgr/detail" "&id=${ ARG_MODULE_DETAIL}"# -S shutdown [[ -n ${ OP_SHUTDOWN} ]] && sandbox_curl_with_exit "sandbox-control/shutdown"# -d debug if [[ -n ${ OP_DEBUG} ]]; then sandbox_debug_curl "module//post/springboot如何进行混淆加密(proguard+xjar)
项目组核心代码模块部署在用户服务器上,面临安全风险,常规部署方式可能导致数据泄露与代码泄露。为解决这一问题,选择采用代码混淆加密技术,确保数据与代码安全。
项目选择proguard作为混淆工具,主要因为其能够有效处理Spring Boot单体应用,通过修改Maven插件配置,结合Jasypt实现配置文件加密。
采用Xjar进行jar包加密,简化配置流程,避免源码泄露与反编译。具体步骤包括下载Xjar demo,将生成的jar包和自定义密码脚本放置在同级目录,使用Maven命令完成混淆代码编译,个人网站源码css并生成加密后的jar包。设置启动脚本添加加密密钥参数,实现安全启动。
混淆前后的对比结果显示,加密处理显著提升了代码和配置文件的安全性,有效防止数据泄露与代码曝光。
总结,通过结合proguard与Xjar,项目实现了高效、安全的代码混淆加密,确保了核心代码模块在部署过程中的安全性。
XJar(防源码泄漏)使用指南
Spring Boot JAR安全加密运行工具,提供了一种对JAR包内资源加密及动态解密运行的方案,旨在避免源码泄露及反编译。该工具支持原生JAR,并基于JDK 1.7或更高版本与Go环境。
功能特性与环境依赖包括:JDK 1.7或以上版本,以及Go环境。底部菜单导航源码为了集成该工具,需要在Maven构建过程中添加依赖,并集成xjar-maven-plugin(GitHub链接:github.com/core-lib/xja...)。
使用步骤如下:
1. 添加依赖于Maven构建文件中。
2. 集成插件:Maven构建自动生成加密后的JAR文件及Go启动器源码。
3. 打包时指定加密密码。完成后,生成的文件包含加密后的JAR包。
4. 下载并安装Go环境(下载地址:golang.google.cn/dl/)。
5. 生成用于启动运行的Go环境下的可执行文件。
6. 使用生成的文件启动运行程序。
万字长文入门Vert.x
关于BIO和NIO,老生常谈的话题,主要分为BIO、NIO和AIO。在实际使用中,BIO和NIO更广泛,NIO相较于BIO,具有更好的并发能力,更节省资源。AIO作为异步非阻塞IO,在当前技术环境下应用还不广泛。
在Java中,BIO、NIO和AIO都支持,NIO在Java 1.7引入为NIO2。实际使用中,netty基于NIO实现,但有自己的模型,本质上都是IO多路复用。需澄清BIO是同步阻塞IO,NIO是同步非阻塞IO,AIO是异步非阻塞IO。
select、poll、epoll和NIO关系主要关注的是区别,它们都是NIO的实现手段。NIO相较于BIO,更具备并发能力,能处理更多请求,但开发成本更高。底层框架或性能敏感场景会考虑使用NIO。
Eclipse Vert.x是一个事件驱动的编程框架,通过抽象提供高性能,让开发者以较低成本享受到NIO优势。Vert.x底层使用netty进行通讯,但对netty细节进行了封装,减少了使用门槛。用户可以基于Vert.x的扩展组件,而netty提供了底层逻辑支持。
使用Vert.x构建简单的HttpServer,只需几行代码,但完整的HttpServer还需处理HTTP协议层面。Vert.x封装了路由功能,通过Router实现。发布Vert.x应用以jar包形式,依赖轻,发布包体积小,适用于服务逻辑复杂度不高且关注性能的场景。
Vert.x提供性能测试,显示相比于Spring,它在多方面表现更优。Vert.x的核心在于黄金法则:永远不要阻塞EventLoop。阻塞会导致无法响应其他事件,引发性能问题。官方文档详细说明了哪些情况可能构成阻塞。
Vert.x提供了executeBlocking方法来处理阻塞代码,通过固定大小线程池避免阻塞事件循环。但推荐避免使用此方法,因为它涉及线程上下文切换,带来性能损耗。Vert.x设计为将连续代码分割,始终在同一个线程上执行,模拟协程运行,以解决阻塞问题。
Vert.x提供了多种原生组件,如vertx-redis-client、vertx-kafka-client等,直接从TCP层面实现协议,实现真正的异步。Context在Vert.x中起串联执行路径、分离阻塞和非阻塞操作的作用,Context原理可通过相关文章了解。
在实际使用中,Vert.x与第三方框架集成时,合理利用Context避免不必要的线程上下文切换。以Caffeine和Failsafe为例,构造实例时通过Context模拟Executor,避免额外线程池的使用。
使用Vert.x native-transport时,引入netty native支持以获取更高性能。需确保netty版本与Vert.x一致,进行额外配置。
实际应用中,通过具体项目Demo展示Vert.x功能,欢迎交流。个人水平有限,可能有疏漏,欢迎提问讨论。推荐关注公众号,获取更多资源。