1. Java中的进程

    本文基于JDK 1.8.0_45 在Java中当涉及到并发的问题的时候我们一般是使用多线程来解决问题,实际上Java中不仅提供了线程的API,同时也提供的进程的API。之所以大家不太使用进程的API解决并发的问题是因为: 进程的创建过于昂贵; 进程的管理依赖于操作系统,不同的操作系统对上层暴露的进程管理的权限是不同的; Java中的进程API是Process这个抽象类,另外提供了ProcessBuilder的构造类来构造进程。Java中的进程API有以下特性: 由于进程的管理依赖于操作系统,Java有些时候不对进程的创建做任何保证; 由于某些操作系统的输入输出流的buffer有限,这导致一些特殊情况下可能读写流会导致进程假死甚至死锁; 环境变量的设置依赖于操作系统,可能操作系统不允许修改环境变量,也可能操作系统的环境变量的字符集是JDK不支持,这可能会导致问题; 以下是一个简单的例子: new ProcessBuilder("ls") .directory(new File("/")) .inheritIO() .start(); 以上代码是构建了一个子进程在根目录下执行ls命令,并将输入输出错误流重定向到JRE默认的对应流中。 另外通过以下代码可以打印所有的系统环境变量: System.out.println(new ProcessBuilder("ls").environment());…

    on JDK8 Process ProcessBuilder 进程

  2. 优雅的在Java应用关闭时清理资源

    本文基于JDK 1.8.0_45 在实际的Java应用中经常会遇到一些类是需要打开资源,如果资源类在使用完毕时可以使用try-with-resources清理关闭资源,但是如果该资源的生命周期是与应用生命周期相同的时候我们该如何在应用关闭时清理关闭资源呢? 在Java中可以使用Runtime注册一个关闭时的钩子,在这个钩子里的代码就会在应用关闭的时候执行,如下所示: Runtime.getRuntime().addShutdownHook(new Thread(() -> { // do something }, "cleanup-thread")); 这种方式注册的线程是一个只初始化了但是没有启动的线程,当JVM开始关闭流程时所有注册的shutdown hook都会被启动并并发执行,在都执行完毕后悔进行可能的退出时的资源清理,然后完全关闭。 另外请注意: 当关闭流程开始之后只有halt方法可以强制关闭JVM; 当关闭流程开始之后禁止注册新的shutdown hook或者去除已注册的shutdown hook; 小心死锁; 建议不要执行太长时间,这是因为一方面用户在关停应用时不会期望等待太长时间,另一方面可能操作系统不会允许太长时间的关停; 如果JVM由于一些特殊的原因终止,比如kill -9,JVM不会保证shutdown hook的执行; 如果在注册了一个shutdown hook之后在一些情况下需要将之删除,可以通过以下代码: Thread shutdownHook = new Thread(() -> { // do…

    on JDK8 java shutdownhook 优雅关闭

  3. try-with-resources

    本文基于JDK 1.8.0_45 在JDK7中提供了一个新的特性:try-with-resources,该特性大大的降低了资源操作时的资源关闭相关的代码,原来的写法如下所示: InputStream stream = new FileInputStream("file.txt"); try { // do something } finally { stream.close(); } 当资源实现了AutoCloseable接口时,新写法如下所示: try (InputStream stream = new FileInputStream("file.txt")) { // do something } 在代码块执行完毕之后会自动调用resource的close方法关闭资源,再也不需要因为忘记关闭资源而导致资源泄露之类的问题了。 在实现该接口时有以下几点最佳实践: 建议在实现的时候抛出具体的异常,如果肯定没有异常发生则不要抛出异常; 如果关闭失败建议放弃继续尝试关闭底层的资源,而只是将其标志为关闭并抛出异常; 建议不要抛出InterruptedException异常以避免潜在的问题; 建议实现为幂等的,以避免多次调用出现问题;…

    on resource java JDK8 try-with-resources

  4. 一个简单的kafka consumer group的监控系统

    当kafka第一次在生产环境上线的时候我们需要对kafka的状态进行监控,如果公司已经有现成的监控报警系统的话事情就会非常简单,只需要将kafka的metrics收集到监控系统中并设置一些报警指标即可。但现实是不是每一家公司都有监控报警系统的,或者现有的监控报警系统由于某种原因暂时无法支持kafka的监控。此时如果安排专人定时去生产环境检查kafka的状态,如果有问题则立即报告给相关人员,这是非常大的成本,姑且不说是否有人,即时有人的时候也不一定就不会出错。程序员的特点之一即是将一切手工的体力活自动化起来,下面我们来介绍如果使用简单的shell脚本去监控kafka的consumer group的状态。 监控脚本 新建脚本如下,脚本命名为kafka-monitor.sh: #!/bin/bash # 修改此处指向正确的kafka home KAFKA_GROUP_COMMAND="/{kafka_home}/kafka-consumer-groups.sh --bootstrap-server kafka1:9092" # 获取kafka的consumer group KAFKA_GROUP_LIST=$($KAFKA_GROUP_COMMAND --list) # 将上面获取到的consumer group转换为数组 eval $(echo $KAFKA_GROUP_LIST | awk '{split(…

    on kafka 监控 monitor consumer group

  5. 跨域问题的解决方式

    下面是一个简单的CORS解决跨域问题的方案: 在服务端的nginx中加入以下配置: server { # 省略 location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Max-Age' 3600;# Tell client that this pre-flight info is valid for 1 hour add_header…

    on 跨域 CORS nginx