【问题标题】:Spring bean how to access server resource only once?Spring bean如何只访问一次服务器资源?
【发布时间】:2017-05-15 02:46:52
【问题描述】:

我有一个 Spring bean,它引用连接工厂来访问 J2C 资源。此代码部署在 2 个负载均衡的 jvm 中的 WebSphere 服务器中。我在 bean xml 中有 readAuth 方法作为 init-method,但在负载测试期间它被多次调用。由于 Spring 单例是每个容器的每个 bean,我假设有多个容器导致它多次加载。所以我删除了 init-method 并将用户名和密码更改为 static 并在 get 方法中添加了 null 检查。但现在,readAuth 方法也被多次调用。我想确保每个 jvm 只调用一次此方法,因为此方法访问服务器资源并且连接在负载测试期间超时。 请就如何编写此类提出最佳方法。提前致谢。

    <bean id="J2CUtils"
        class="test.J2CUtils">
        <property name="connectionFactory" ref="connectionFactory" />
    </bean>
    <jee:jndi-lookup id="connectionFactory" jndi-name="eis/J2CAuth" />

public class J2Ctils {
    private ConnectionFactory connectionFactory;
    private static String userName;
    private static String password;

    private void readAuth() throws ResourceException {
        System.out.println("Auth loaded");
            Connection conn = connectionFactory.getConnection();
            Interaction interaction = (Interaction) conn.createInteraction();
            Config config = interaction.getConfig();
            userName = config.getUserName();
            password = config.getPassword();
    }
    public String getUserName() {
        if(null == userName) {
            readAuth();
        }
        return userName;
    }
    public String getPassword() {
        if(null == password) {
            readAuth();
        }
        return password;
    }
    public void setConnectionFactory(ConnectionFactory connectionFactory) {
        this.connectionFactory = connectionFactory;
    }
}

【问题讨论】:

    标签: spring ioc-container


    【解决方案1】:

    如果您想只访问一次资源,那么单例或静态方法将无济于事,因为集群的每个成员都有自己的类实例。

    请记住,Java EE 规范 Spring specification 都没有定义任何类型的集群行为。您需要搜索特定的供应商解决方案来实现这种需求。就像一个例子,看看@ApplicationScped in a cluster

    存档预期行为的其他方法是使用分布式锁,如 Zookeeper,甚至可能使用带有duplicate message filter 的队列。

    【讨论】:

    • 集群中有2个jvm。如果集群中每个 jvm 有一个实例,我可以。但是 2 分钟和 5 分钟的负载测试显示该方法被调用了 7 次和 12 次。对于 30,000 个请求,我使用 4 个 jvm 获得了大约 100 个连接超时。所以我的意图是避免这些连接超时。有没有一种方法可以确保每个 jvm 使用静态类/方法/变量只有一个实例?
    • 默认 Spring Bean 是单例,即每个 JVM 只存在一次。如果将getUserName()getPassword() 标记为synchronized readAuth() 每个bean 将只调用一次,除非用户名或密码为null 或spring 上下文被重新加载。
    猜你喜欢
    • 2020-02-23
    • 2021-12-26
    • 2018-12-26
    • 1970-01-01
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    相关资源
    最近更新 更多