jvm运行在docker之类的容器中会有哪些问题? Docker之类容器和虚拟机非常相似: Docker 并不是一种完全的虚拟化技术,而更是一种轻量级的隔离技术。如下图 虚拟机会独立运行一个操作系统,容器则没有,仅仅是使用隔离的技术;所以容器省略了虚拟操作系统的开销,实现了轻量级的目标;
Java 平台来说,容器带来了很多意外的困难,主要体现在几个方面: 第一,容器环境对于计算资源的管理方式是全新的,CGroup 作为相对比较新的技术,历史版本的 Java 显然并不能自然地理解相应的资源限制。 第二,namespace 对于容器内的应用细节增加了一些微妙的差异,比如 jcmd、jstack 等工具会依赖于“/proc//”下面提供的部分信息,但是 Docker 的设计改变了这部分信息的原有结构,我们需要对原有工具进行修改以适应这种变化。
JVM 根据系统资源(内存、CPU 等)情况,在启动时设置默认参数。这就是所谓的Ergonomics机制,例如: JVM 会大概根据检测到的内存大小,设置最初启动时的堆大小为系统内存的 1/64;并将堆最大值,设置为系统内存的 1/4。 JVM 检测到系统的CPU核数,则直接影响到了 Parallel GC 的并行线程数目和 JIT complier 线程数目。 Java设置的默认参数很可能是基于错误信息而做出的。这就类似,我以为我住的是整栋别墅,实际上却只有一个房间是给我住的。
JVM 的一些原有诊断或备用机制也会受到影响。为保证服务的可用性,一种常见的选择是依赖“-XX:OnOutOfMemoryError”功能,通过调用处理脚本的形式来做一些补救措施,比如自动重启服务等。但是,这种机制是基于 fork 实现的,当 Java 进程已经过度提交内存时,fork 新的进程往往已经不可能正常运行了。
如何解决上面的问题:-----使用最新版本的jdk JDK9中引入了一些实验性的参数:如-XX:+UnlockExperimentalVMOptions JDK10对容器(Docker)的支持已经比较完善:默认就会自适应各种资源限制和实现差异。
如果必须使用老版本的jdk,那就需要自己根据docker的配置,尽量具体设置jdk一些参数,包括: 堆大小、GC和JIT并行线程数等
java应用安全,涉及哪些安全机制? 1 运行时安全机制: 类的加载:验证Java语义和标准 双亲加载模型 2 Java 提供的安全框架 API 加解密API HTTPS相关通信协议的红丝线 3 jdk集成的安全工具 keytool 管理安全场景中的秘钥、证书等,并且可以管理Java程序使用的keystore文件。 jarsigner,用于对 jar 文件进行签名或者验证。
什么是安全漏洞?什么是注入攻击? 注入攻击 sql注入:参数中带有sql '' or ''='' 操作系统命令注入: 原本执行 ls -al dir_name 输入的dir_name为 dir_name;rm -rf ./* xml注入:
sql注入攻击解决: 输入阶段进行输入限制,如不允许标点符号等 preparestatement代替动态sql 数据库层面,对查询修改进行合理限制,查询的使用仅有查询权限账号;
DOS (Denial-Of-Service attack) 攻击者可以事先构造大量相同哈希值的数据,然后以 JSON 数据的形式发送给服务器端,服务器端在将其构建成为 Java 对象过程中,通常以 Hastable 或 HashMap 等形式存储,哈希碰撞将导致哈希表发生严重退化,算法复杂度可能上升一个数量级,耗费cpu,导致正常访问无法响应; dos攻击如何避免? 使用最新的jdk,避免已暴露的问题,如hash碰撞 合理限制,如文件大小\如sql查询结果大小 资源释放,库连接、锁、流关闭
如何写出安全的java代码: 开发前的预设计 :防注入、dos攻击的策略使用、token和调用策略 开发: 规范化:线程池自定义、流关闭、新版本jdk、map初始化大小 重要信息加密:注意防泄漏、传输加密、保存加密、序列化合理使用(transient保护关键信息) 代码优化:int溢出 if(a+b<c)--> if(a<c-b)
后期测试: 工具使用:findBugs工具分析