Hazelcast 如何为SPI编写客户端代理以及客户端代理和服务器代理之间的区别是什么?

Hazelcast 如何为SPI编写客户端代理以及客户端代理和服务器代理之间的区别是什么?,hazelcast,Hazelcast,我基于HazelcastidGenerator类开发了自己的idGenerator(将每个上次使用的id存储到数据库中)。现在我想将hazelcast集群作为单个java应用程序运行,将我的web应用程序作为其他应用程序运行(web应用程序重启不应将id值移动到下一个块)。我将MyIdGeneratorProxy和MyIdGeneratorService移动到新的应用程序,运行它,将web应用程序作为hazelcast客户端运行,并获取 IllegalArgumentException: No

我基于Hazelcast
idGenerator
类开发了自己的idGenerator(将每个
上次使用的id
存储到数据库中)。现在我想将hazelcast集群作为单个java应用程序运行,将我的web应用程序作为其他应用程序运行(web应用程序重启不应将id值移动到下一个块)。我将
MyIdGeneratorProxy
MyIdGeneratorService
移动到新的应用程序,运行它,将web应用程序作为hazelcast客户端运行,并获取

IllegalArgumentException: No factory registered for service: ecs:impl:idGeneratorService
当客户端和服务器是同一个应用程序时,一切正常


如果没有一些
clientProxy
,它似乎无法处理。我比较了
IdGeneratorProxy
ClientIdGeneratorProxy
,结果看起来是一样的。这个主意是什么?如何为服务编写客户端代理?我还没有找到任何文件。调查方向正确吗?我认为可以将hazelcast内部服务(如id生成器服务)和我的业务流程分开。我应该在我的web应用程序中存储自定义ClientProxy(用于自定义spi吗?

这是一个如何创建客户端代理的演示,缺少的部分
CustomClientProxy
函数调用非常复杂(更像服务器代理,这里称为
ReadRequest
,服务器称为
Operation
),您可以找到一个how-AtomicLong。对于每个客户端代理方法,您都必须发出请求

@Test
public void client() throws InterruptedException, IOException
{
    ClientConfig cfg = new XmlClientConfigBuilder("hazelcast-client.xml").build();
    ServiceConfig serviceConfig = new ServiceConfig();
    serviceConfig.setName(ConnectorService.NAME)
                 .setClassName(ConnectorService.class.getCanonicalName())
                 .setEnabled(true);
    ProxyFactoryConfig proxyFactoryConfig = new ProxyFactoryConfig();
    proxyFactoryConfig.setService(ConnectorService.NAME);
    proxyFactoryConfig.setClassName(CustomProxyFactory.class.getName());
    cfg.addProxyFactoryConfig(proxyFactoryConfig);
    HazelcastInstance hz = HazelcastClient.newHazelcastClient(cfg);

    Thread.sleep(1000);
    for (int i = 0; i < 10; i++)
    {
        Connector c = hz.getDistributedObject(ConnectorService.NAME, "Connector:" + ThreadLocalRandom.current()
                                                                                                     .nextInt(10000));
        System.out.println(c.snapshot());
    }
}

private static class CustomProxyFactory implements ClientProxyFactory
{

    @Override
    public ClientProxy create(String id)
    {
        return new CustomClientProxy(ConnectorService.NAME, id);
    }
}

private static class CustomClientProxy extends ClientProxy implements Connector
{
    protected CustomClientProxy(String serviceName, String objectName)
    {
        super(serviceName, objectName);
    }

    @Override
    public ConnectorState snapshot()
    {
        return null;
    }

    @Override
    public void loadState(ConnectorState state)
    {

    }

    @Override
    public boolean reconnect(HostNode node)
    {
        return false;
    }

    @Override
    public boolean connect()
    {
        return false;
    }

}

我还制作了一个序列(与IdGenerate相同),这是由zookeeper或redis支持的,而且添加db后端也很容易。如果有时间,我将集成到hazelcast。

你可能想看看snowcast()我是如何做到的。@noctarius你应该用一段代码来回答,而不是显示链接。这只是一个注释的原因,要把一个代码示例放在一起,我需要更多的时间——至少到目前为止,它似乎有助于你回答自己的感谢,@noctarius!Snowcast是一个伟大的项目,在一瞬间探索它的所有代码库并不是那么容易,但我将继续尝试。可以给我一些额外的建议来完成我的调查吗?你自己是如何学习的?我自己为Hazelcast工作:)目前SPI没有很好的文档记录,它可能会不时发生轻微的变化(从3.4.x到3.5,如果你看一下最新的提交,你会发现我已经解决了它),因此还没有一个真正好的阅读点,对不起:)谢谢你,@wener,这种方法是有效的(您可以删除ServiceConfig实例的定义,它是冗余的)。感谢您链接到AtomicLong实现。现在我尝试扩展现有的,没有操作。你知道为什么吗?我应该如何阅读才能正确理解此主题?没有ReadRequest,因为IdGenerator是的包装器,您应该检查IATOMCLONG。
API
interface MyIdGenerate
Server
MyIdGenerateService
MyIdGenerateProxy
MyIdGenerateXXXOperation
Client
ClientMyIdGenerateFactory
ClientMyIdGenerateProxy
MyIdGenerateXXXRequest