我们在Glassfish 3.1.2集群上部署了一个Java EE应用程序,该集群使用JAX-RS提供REST API。我们定期通过将EAR部署到重复的集群实例来部署新版本的应用程序,然后更新HTTP负载平衡器,以将流量发送到更新的实例,而不是旧实例。
这使我们能够在不损失可用性的情况下进行升级,如下所述:http://docs.oracle.com/cd/E18930_01/html/821-2426/abdio.html#abdip.我们经常对应用程序进行重大更改,这使得新版本“不兼容”(这就是为什么我们使用两个集群)。
我们现在必须为应用程序提供一个消息队列接口,用于一些高吞吐量的内部消息传递(来自C生产者)。然而,使用消息驱动Beans,我看不出如何在没有任何服务中断的情况下升级应用程序?
我调查过的选项有:
单个远程JMS队列(openMQ)
生产者将消息发送到单个消息队列,消息由MDB处理。当我们启动第二个集群实例时,消息应该负载均衡到升级的集群,但是当我们停止“旧”集群时,未完成的事务将丢失。
我考虑过在升级期间使用JMX禁用消息队列的生产者/消费者,但这只会暂停消息传递。当我们禁用旧集群时(我想是吧?)。
我还考虑放弃@MessageDriven注释并手动创建MessageConsumer。这似乎是可行的,但MessageConsumer随后无法使用EJB注释访问其他EJB(据我所知):
// Singleton bean with start()/stop() functions that
// enable/disable message consumption
@Singleton
@Startup
public class ServerControl {
private boolean running=false;
@Resource(lookup = "jms/TopicConnectionFactory")
private TopicConnectionFactory topicConnectionFactory;
@Resource(lookup = "jms/MyTopic")
private Topic topic;
private Connection connection;
private Session session;
private MessageConsumer consumer;
public ServerControl()
{
this.running = false;
}
public void start() throws JMSException {
if( this.running ) return;
connection = topicConnectionFactory.createConnection();
session = dbUpdatesConnection.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
consumer = dbUpdatesSession.createConsumer(topic);
consumer.setMessageListener(new MessageHandler());
// Start the message queue handlers
connection.start();
this.running = true;
}
public void stop() throws JMSException {
if( this.running == false ) return;
// Stop the message queue handlers
consumer.close();
this.running = false;
}
}
// MessageListener has to invoke functions defined in other EJB's
@Stateless
public class MessageHandler implements MessageListener {
@EJB
SomeEjb someEjb; // This is null
public MessageHandler() {
}
@Override
public void onMessage(Message message) {
// This works but someEjb is null unless I
// use the @MessageDriven annotation, but then I
// can't gracefully disconnect from the queue
}
}
每个集群的本地/嵌入式JMS队列
替代消息队列提供程序
我假设仅仅禁用该应用程序将“杀死”任何未完成的事务。如果禁用该应用程序允许现有事务完成,那么我可以在启动第二个集群后执行该操作。
任何帮助都将不胜感激!提前谢谢。
我不理解你的假设,即当我们停止“旧”集群时,未完成的事务将丢失。MDB将被允许在应用程序停止之前完成消息处理,任何未确认的消息将由“新”集群处理。
如果旧版本和新版本之间的负载平衡是一个问题,我将把MDB放在单独的中。耳朵
,并在新MDB上线后立即停止旧的MDB,甚至在此之前,如果您的用例允许延迟消息处理,直到部署新版本。
如果使用高可用性,那么集群的所有消息将存储在单个数据存储中,而不是每个实例上的本地数据存储中。然后可以将两个集群配置为使用同一存储。然后,当关闭旧的和旋转新的你有权访问所有的消息。
这是一个很好的视频,有助于解释glassfish的高可用性jms。
SWarm mode 与滚动升级 在 部署服务 一节中我们使用 nginx:1.13.7-alpine 镜像部署了一个名为 nginx 的服务。 现在我们想要将 NGINX 版本升级到 1.13.12,那么在 Swarm mode 中如何升级服务呢? 你可能会想到,先停止原来的服务,再使用新镜像部署一个服务,不就完成服务的 “升级” 了吗。 这样做的弊端很明显,如果新部署的服务出现问题,原来的服务
我试图在一个libgdx游戏中实现触摸滚动。我有一个很宽的图像,是一个房间的全景。我希望能够滚动图像,让用户可以看到房间的四周。我有它,所以我可以滚动一定的距离,但当一个新的触摸拖动事件被注册的图像被移回到原来的位置。 这就是我实现它的方式 } 在InputProcessor中 在这个问题LibGdx如何使用OrthographicCamera?滚动的帮助下,我做到了这一步?。然而,这并没有真正解
问题内容: 我一直在做一个项目,内容已经完成。但是对于设计,我正在考虑使用视差滚动技术。 但是,我所能找到的全部还是JavaScript或Jquery,而我只精通CSS3。 可以仅使用CSS3(如果需要使用HTML5)而不是使用jquery插件来实现视差滚动吗?如果我能指出一些相同的教程,那就太好了。 注意:这接近于我想要产生的效果 问题答案: 要产生非常基本的视差滚动效果,下面的示例就足够了。
是否可以混合事务程序化和基于注释的管理?默认情况下,@Transactional会在任何运行时进行回滚并重新抛出它。 我不想重播它,但返回可选。空()有可能吗?使用事务编程管理很容易实现:(我从Spring文档中获取了示例) 有可能以一种好的方式将它们结合起来吗?让我们说: 你认为,混合使用两种管理事务的方法是一种代码气味吗? 谢谢你。
PS Vita的系统软件会随着不断的升级而逐渐追加各种功能或强化安全性。请随时升级为最新版本。 身处有可使用接入点的场所时,轻触[系统升级]>[使用Wi-Fi进行升级],可通过Wi-Fi连接互联网,下载最新的升级文件。请遵循画面指示正确操作。 重要 请勿于升级时切断主机的电源或强制取出PS Vita专用存储卡。升级若遭到中断,可能会导致故障。 电池电量低时,可能无法开始升级。 升级中无法使用电源键
当有镜像发布新版本,新版本服务上线时如何实现服务的滚动和平滑升级? 如果你使用ReplicationController创建的pod可以使用kubectl rollingupdate命令滚动升级,如果使用的是Deployment创建的Pod可以直接修改yaml文件后执行kubectl apply即可。 Deployment已经内置了RollingUpdate strategy,因此不用再调用kub