在Java中使用System.getenv()的性能影响

3

我有一个使用Jersey构建的java REST web服务,出于安全原因,我想将 DriverManager.getConnection();方法的参数:Url、用户名和密码保存在操作系统环境变量中。

由于每个请求都需要创建自己的数据库连接,我想知道调用System.getenv("key");是否会存在性能问题?

这种做法的灵感来自于这篇文章:http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/java-rds.html#java-rds-javase

是否有更好的选择?例如:

public class EnvironmentHelper {
    static final String URL;
    static final String USERNAME;
    static final String PASSWORD;

    static {
        URL = System.getenv("URL");
        USERNAME = System.getenv("USERNAME");
        PASSWORD = System.getenv("PASSWORD");
    }
}

这样我只加载一次变量,对吗?无论我收到多少请求。

3
每个System.getenv的执行时间应该与哈希查找的时间相当,对性能影响应该为零。如果您担心性能问题,可以自行进行性能分析。 - ajb
4
与打开连接并执行操作相比,getenv() 函数的开销微不足道。但是,这种技术并不比常规技术更安全。如果攻击者可以访问您的 context.xml 文件,那么他也可以获取到这个函数的信息。 - user207421
@EJP,是的,您说得对。减小每次打开连接的影响的唯一解决方案是使用连接池,对吗? - Luiz
1
@Luiz,没错。 - user207421
2个回答

7

System.getEnv(name) 可以翻译为 ProcessEnvironment.getEnv,它实际上是对 HashMap 的查找(ProcessEnvironment 是 HashMap 的扩展)。这个 HashMap 在静态块中加载,该块在类初始化时运行 - 因此,在很大概率下,查找速度非常快,O(1)。


1
我怀疑与每个请求创建一个新连接相比,调用getenv可能不会造成更大的性能问题,但我认为如果采用您在上面使用的静态加载方法来解决问题,这将是最好的选择。这消除了为每个新连接搜索环境列表的任务。
根据getenv函数的操作系统手册,它确实需要搜索环境列表以查找值,但从我的C知识中得知,这不需要系统调用,因为环境变量被复制到程序中。

由于它是线程安全的,每次调用也必须锁定互斥量,对吗? - Luiz
@Luiz 不,它不是线程安全的:“getenv() 的实现不要求可重入”。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接