Pivotal GemFire无法查看Gfsh或Pulse中的缓存数据

时间:2018-07-31 19:10:53

标签: gemfire geode spring-data-gemfire

我创建了一个带有Geode / GemFire缓存的Spring Boot应用程序。我想用我的Spring Boot应用程序连接到Gfsh创建的Region。在我的application-context.xml中,我使用的是gfe:lookup-region,其ID为Gfsh创建的Region。

在我的Java配置文件中,我使用LookupRegionFactoryBean来获取对外部定义的Region的引用。

在我的SpringBootApplication引导类中,由于可以读回所有保存的对象,因此我成功地写入了存储库。但是,使用Gfsh工具或Pulse工具时,我看不到缓存的数据记录(或保存的计数)。

您能在这里提供一些见解吗?另外,我也尝试在配置文件中使用LocalRegionFactoryBean,但是该方法也不起作用。

谢谢。

    application-context.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
           xmlns:gfe-data="http://www.springframework.org/schema/data/gemfire"
           xmlns:gfe="http://www.springframework.org/schema/gemfire"
           xmlns:util="http://www.springframework.org/schema/util"
           xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/data/gemfire http://www.springframework.org/schema/data/gemfire/spring-data-gemfire.xsd http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd">

        <context:component-scan base-package="com.example.geode"></context:component-scan>

        <util:properties id="gemfireProperties" location="context:geode.properties"/>

    <!--    <context:property-placeholder location="context:geode.properties"/>

        <bean id="log-level"><property name="log-level" value="${log-level}"/></bean>
        <bean id="mcast-port"><property name="mcast-port" value="${mcast-port}"/></bean>
        <bean id="name"><property name="name" value="${name}"/></bean>-->

        <gfe:annotation-driven/>
        <gfe-data:function-executions base-package="com.example.geode.config"/>
        <!-- Declare GemFire Cache -->
    <!--    <gfe:cache/>    -->
        <gfe:cache properties-ref="gemfireProperties"/>

        <!-- Local region for being used by the Message -->
    <!--    <gfe:replicated-region id="employee" value-constraint="com.example.geode.model.Employee" data-policy="REPLICATE"/>-->
        <gfe:lookup-region id="employee" value-constraint="com.example.geode.model.Employee" data-policy="REPLICATE"/>
    <!--        <gfe:local-region id="employee" value-constraint="com.example.geode.model.Employee" data-policy="REPLICATE"/>-->
        <!-- Search for GemFire repositories -->
        <gfe-data:repositories base-package="com.example.geode.repository"/>


    </beans>

    GeodeConfiguration.java:

    //imports not included

    @Configuration

    @ComponentScan
    @EnableCaching
    @EnableGemfireRepositories//(basePackages = "com.example.geode.repository")
    @EnableGemfireFunctions
    @EnableGemfireFunctionExecutions//(basePackages = "com.example.geode.function")

    @PropertySource("classpath:geode.properties")

    public class GeodeConfiguration {

        @Autowired
        private EmployeeRepository employeeRepository;

        @Autowired
        private FunctionExecution functionExecution;

        @Value("${log-level}") 
        private String loglevel;
        @Value("${mcast-port}") 
        private String mcastPort; 
        @Value("${name}")
        private String name;    

        Properties gemfireProperties() {

            Properties gemfireProperties = new Properties();
            gemfireProperties.setProperty(loglevel, loglevel);
            gemfireProperties.setProperty(mcastPort, mcastPort);
            gemfireProperties.setProperty(name, name);

            return gemfireProperties;
        }  

        @Bean
        CacheFactoryBean gemfireCache() {

            return new CacheFactoryBean();
        }

        @Bean
        GemfireCacheManager cacheManager() {

            GemfireCacheManager cacheManager = new GemfireCacheManager();
            try {
                CacheFactoryBean cacheFactory = gemfireCache();
                //gemfireProperties();
                //cacheFactory.setProperties(gemfireProperties());
                cacheManager.setCache(cacheFactory.getObject()); //gemfireCache().getObject());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return cacheManager;
        }

        @Bean(name="employee")
        //@Autowired
        LookupRegionFactoryBean<String, Employee> getRegion(final GemFireCache cache) 
                throws Exception {

            //CacheTypeAwareRegionFactoryBean<String, Employee> region = new CacheTypeAwareRegionFactoryBean<>();//GenericRegionFactoryBean<> //LocalRegionFactoryBean<>();

            LookupRegionFactoryBean<String, Employee> region = new LookupRegionFactoryBean<>();//GenericRegionFactoryBean<> //LocalRegionFactoryBean<>();        

            region.setRegionName("employee");

            try {
                    region.setCache(gemfireCache().getObject());
            } catch (Exception e) {
                    e.printStackTrace();
            }        
            //region.setClose(false);
            region.setName("employee");    
            //region.setAsyncEventQueues(new AsyncEventQueue[]{gemfireQueue});       
            //region.setPersistent(false);
            //region.setDataPolicy(org.apache.geode.cache.DataPolicy.REPLICATE);  //PRELOADED);   //REPLICATE);  
            region.afterPropertiesSet();

            return region;
        }

    }

    BasicGeodeApplication.java:

    //imports not provided

    @EnableGemfireRepositories
    @SpringBootApplication

    @ComponentScan("com.example.geode")
    //@EnableCaching
    @EnableGemfireCaching
    @EnableEntityDefinedRegions(basePackageClasses = Employee.class)

    @SuppressWarnings("unused")
    //@CacheServerApplication(name = "server2", locators = "localhost[10334]",
    //    autoStartup = true, port = 41414)
    public class BasicGeodeApplication {

        @Autowired
        private EmployeeRepository employeeRepository;

        @Autowired
        private EmployeeService employeeService;

        private static ConfigurableApplicationContext context;

        public static void main(String[] args) {

            context = SpringApplication.run(BasicGeodeApplication.class, args);


            BasicGeodeApplication bga = new BasicGeodeApplication();

        }

        @Bean
        public ApplicationRunner run(EmployeeRepository employeeRepository) {

            return args -> {

                Employee bob = new Employee("Bob", 80.0);
                Employee sue = new Employee("Susan", 95.0);
                Employee jane = new Employee("Jane", 85.0);
                Employee jack = new Employee("Jack", 90.0);

                List<Employee> employees = Arrays.asList(bob, sue, jane, jack);
                employees.sort(Comparator.comparing(Employee::getName));

                for (Employee employee : employees) {

                    //employeeService.saveEmployee(employee);
                    employeeRepository.save(employee);
                }

                System.out.println("\nList of employees:");

                employees //Arrays.asList(bob.getName(), sue.getName(), jane.getName(), jack.getName());
                    .forEach(person -> System.out.println("\t" + employeeRepository.findByName(person.getName())));

                System.out.println("\nQuery salary greater than 80k:");

                stream(employeeRepository.findBySalaryGreaterThan(80.0).spliterator(), false)
                    .forEach(person -> System.out.println("\t" + person));

                System.out.println("\nQuery salary less than 95k:");

                stream(employeeRepository.findBySalaryLessThan(95.0).spliterator(), false)
                    .forEach(person -> System.out.println("\t" + person));

                System.out.println("\nQuery salary greater than 80k and less than 95k:");

                stream(employeeRepository.findBySalaryGreaterThanAndSalaryLessThan(80.0, 95.0).spliterator(), false)
                    .forEach(person -> System.out.println("\t" + person));

            };

        }


    @Service 
    class EmployeeService {   

        @Autowired
        private EmployeeRepository employeeRepository;

        @CachePut(cacheNames = "employee", key = "#id")
        //@PutMapping("/")
        void saveEmployee(Employee employee) {

            employeeRepository.save(employee);
        }

        Employee findEmployee(String name) {

            return null;
        }
        //employeeRepository.findByName(person.getName())));
    }

    } 

    EmployeeRepository.java:


    @Repository("employeeRepository")
    //@DependsOn("gemfireCache")
    public interface EmployeeRepository extends CrudRepository<Employee, String> {

        Employee findByName(String name);

        Iterable<Employee> findBySalaryGreaterThan(double salary);

        Iterable<Employee> findBySalaryLessThan(double salary);

        Iterable<Employee> findBySalaryGreaterThanAndSalaryLessThan(double salary1, double salary2);
    }



Employee.java:

// imports not included

@Entity
@Region("employee")
public class Employee implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)    
    @javax.persistence.Id
    private Long id;
    public String name;
    public double salary;

    protected Employee() {}

    @PersistenceConstructor
    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    @Override
    public String toString() {
        return name + " salary is: " + salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }
}

1 个答案:

答案 0 :(得分:2)

如果您的Spring Boot应用程序实际上使用了在尝试查找后在Gfsh中创建的Region,我会感到非常惊讶。从以下事实也可以明显看出这一点:在运行应用程序后使用 Gfsh Pulse 时,您无法在Region中看到数据。

此外,由于您尚未共享geode.properties文件的内容,因此从您的配置中并不能完全清楚Spring Boot应用程序是否要加入以 Gfsh 开头的集群。 / p>

  

注意:由于您如何引用属性文件,因此我们将稍后返回您的属性文件(例如,在Spring {的context:元素的location属性中使用<util> {1}}模式)甚至都不正确。实际上,您的整个XML文件甚至无效!除非抽象,否则没有Util的Bean定义将无效。

您正在使用哪个版本的Spring Boot和Spring Data Geode / GemFire(SDG)?

从XML配置文件中的Spring XML模式引用来看,您正在使用Spring 3.0!您不应在架构位置声明中引用版本。不合格的架构版本将根据您在应用程序类路径上导入的Spring JAR(例如,使用Maven)进行版本控制。

无论如何,我想问的原因是,我对SDG进行了许多更改,导致在配置不明确或不完整的情况下(对于instance,它会快速失败)。

在您的情况下,如果地区不存在,查找将立即失败。而且,我可以肯定不存在Region(一个或多个),因为默认情况下,对等缓存节点/应用程序上的SDG disables Cluster Configuration。因此,您在 Gfsh 中创建的Region都不可立即用于您的Spring Boot应用程序。

因此,让我们来看一个简单的例子。我将主要使用SDG的新annotation configuration model并结合一些Java配置,以易于使用和方便。鉴于您的配置无处不在,我鼓励您阅读SDG参考指南中的这一章,并且我可以肯定的是,您确实混淆了正在发生的事情。

这是我的Spring Boot,Apache Geode应用程序...

class

我正在使用 Spring数据 @SpringBootApplication @SuppressWarnings("unused") public class ClusterConfiguredGeodeServerApplication { public static void main(String[] args) { SpringApplication.run(ClusterConfiguredGeodeServerApplication.class, args); } @Bean ApplicationRunner runner(GemfireTemplate customersTemplate) { return args -> { Customer jonDoe = Customer.named("Jon Doe").identifiedBy(1L); customersTemplate.put(jonDoe.getId(), jonDoe); }; } @PeerCacheApplication(name = "ClusterConfiguredGeodeServerApplication") @EnablePdx static class GeodeConfiguration { @Bean("Customers") LookupRegionFactoryBean<Long, Customer> customersRegion(GemFireCache gemfireCache) { LookupRegionFactoryBean<Long, Customer> customersRegion = new LookupRegionFactoryBean<>(); customersRegion.setCache(gemfireCache); return customersRegion; } @Bean("CustomersTemplate") GemfireTemplate customersTemplate(@Qualifier("Customers") Region<?, ?> customers) { return new GemfireTemplate(customers); } } @Data @RequiredArgsConstructor(staticName = "named") static class Customer { @Id private Long id; @NonNull private String name; Customer identifiedBy(Long id) { this.id = id; return this; } } } (其中包括 Apache Geode的 Spring数据 Lovelace RC1)。我还使用了Spring Boot 2.1.0.RC1,它引入了核心Spring Framework 2.0.3.RELEASE,全部基于Java 8。

我省略了包装和进口声明。

我正在使用Project Lombok定义我的5.0.7.RELEASE类。

我有一个嵌套的Customer类,用于将Spring Boot应用程序配置为能够加入Apache Geode集群的“对等” GeodeConfiguration成员。但是,它还不属于任何群集!

最后,我配置了一个“客户”区域,该区域在Spring上下文中被“查找”。

启动此应用程序时,它失败了,因为无论如何都没有定义“客户”区域...

Cache

这是预期的!

好的,让我们进入 Gfsh 并启动一个集群。

您知道您需要使用服务器启动定位器以形成集群,对吗?定位器由试图加入群集的其他潜在对等方使用,以便他们可以首先定位群集。由于无法在定位器上创建区域,因此需要服务器才能创建“客户”区域。

Caused by: org.springframework.beans.factory.BeanInitializationException: Region [Customers] in Cache [GemFireCache[id = 2126876651; isClosing = false; isShutDownAll = false; created = Thu Aug 02 13:43:07 PDT 2018; server = false; copyOnRead = false; lockLease = 120; lockTimeout = 60]] not found
    at org.springframework.data.gemfire.ResolvableRegionFactoryBean.createRegion(ResolvableRegionFactoryBean.java:146) ~[spring-data-geode-2.1.0.RC1.jar:2.1.0.RC1]
    at org.springframework.data.gemfire.ResolvableRegionFactoryBean.afterPropertiesSet(ResolvableRegionFactoryBean.java:96) ~[spring-data-geode-2.1.0.RC1.jar:2.1.0.RC1]
    at org.springframework.data.gemfire.LookupRegionFactoryBean.afterPropertiesSet(LookupRegionFactoryBean.java:72) ~[spring-data-geode-2.1.0.RC1.jar:2.1.0.RC1]
    ...

现在,即使我再次运行Spring Boot应用程序,它仍然会因相同的异常而失败...

$ echo $GEODE_HOME
/Users/jblum/pivdev/apache-geode-1.6.0

$ gfsh
    _________________________     __
   / _____/ ______/ ______/ /____/ /
  / /  __/ /___  /_____  / _____  / 
 / /__/ / ____/  _____/ / /    / /  
/______/_/      /______/_/    /_/    1.6.0

Monitor and Manage Apache Geode

gfsh>start locator --name=LocaorOne --log-level=config
Starting a Geode Locator in /Users/jblum/pivdev/lab/LocaorOne...
....
Locator in /Users/jblum/pivdev/lab/LocaorOne on 10.0.0.121[10334] as LocaorOne is currently online.
Process ID: 41758
Uptime: 5 seconds
Geode Version: 1.6.0
Java Version: 1.8.0_152
Log File: /Users/jblum/pivdev/lab/LocaorOne/LocaorOne.log
JVM Arguments: -Dgemfire.enable-cluster-configuration=true -Dgemfire.load-cluster-configuration-from-dir=false -Dgemfire.log-level=config -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806
Class-Path: /Users/jblum/pivdev/apache-geode-1.6.0/lib/geode-core-1.6.0.jar:/Users/jblum/pivdev/apache-geode-1.6.0/lib/geode-dependencies.jar

Successfully connected to: JMX Manager [host=10.0.0.121, port=1099]

Cluster configuration service is up and running.

gfsh>start server --name=ServerOne --log-level=config
Starting a Geode Server in /Users/jblum/pivdev/lab/ServerOne...
...
Server in /Users/jblum/pivdev/lab/ServerOne on 10.0.0.121[40404] as ServerOne is currently online.
Process ID: 41785
Uptime: 3 seconds
Geode Version: 1.6.0
Java Version: 1.8.0_152
Log File: /Users/jblum/pivdev/lab/ServerOne/ServerOne.log
JVM Arguments: -Dgemfire.default.locators=10.0.0.121[10334] -Dgemfire.start-dev-rest-api=false -Dgemfire.use-cluster-configuration=true -Dgemfire.log-level=config -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806
Class-Path: /Users/jblum/pivdev/apache-geode-1.6.0/lib/geode-core-1.6.0.jar:/Users/jblum/pivdev/apache-geode-1.6.0/lib/geode-dependencies.jar

gfsh>list members
  Name    | Id
--------- | --------------------------------------------------------------
LocaorOne | 10.0.0.121(LocaorOne:41758:locator)<ec><v0>:1024 [Coordinator]
ServerOne | 10.0.0.121(ServerOne:41785)<v1>:1025

gfsh>list regions
No Regions Found

gfsh>create region --name=Customers --type=PARTITION --key-constraint=java.lang.Long --value-constraint=java.lang.Object
 Member   | Status
--------- | ------------------------------------------
ServerOne | Region "/Customers" created on "ServerOne"

gfsh>list regions
List of regions
---------------
Customers

gfsh>describe region --name=Customers
..........................................................
Name            : Customers
Data Policy     : partition
Hosting Members : ServerOne

Non-Default Attributes Shared By Hosting Members  

 Type  |    Name     | Value
------ | ----------- | ---------
Region | size        | 0
       | data-policy | PARTITION

为什么?

这是因为1)Spring Boot Apache Geode对等体Caused by: org.springframework.beans.factory.BeanInitializationException: Region [Customers] in Cache [GemFireCache[id = 989520513; isClosing = false; isShutDownAll = false; created = Thu Aug 02 14:09:25 PDT 2018; server = false; copyOnRead = false; lockLease = 120; lockTimeout = 60]] not found at org.springframework.data.gemfire.ResolvableRegionFactoryBean.createRegion(ResolvableRegionFactoryBean.java:146) ~[spring-data-geode-2.1.0.RC1.jar:2.1.0.RC1] at org.springframework.data.gemfire.ResolvableRegionFactoryBean.afterPropertiesSet(ResolvableRegionFactoryBean.java:96) ~[spring-data-geode-2.1.0.RC1.jar:2.1.0.RC1] at org.springframework.data.gemfire.LookupRegionFactoryBean.afterPropertiesSet(LookupRegionFactoryBean.java:72) ~[spring-data-geode-2.1.0.RC1.jar:2.1.0.RC1] ... 应用程序尚未包含在集群中; 2)默认情况下,SDG不允许Spring配置/引导的Apache Geode对等体{ {1}}应用程序才能从群集(特别是Cluster Configuration Service)获得配置,因此,我们必须同时配置/启用这两项。

我们可以通过将Cache批注的Cache属性指定为Cache来使Spring Boot,Apache Geode对等locators应用程序加入集群。

@PeerCacheApplication

我们可以让我们的Spring Boot Apache Geode对等localhost[10334]应用程序通过启用@PeerCacheApplication(name = "...", locators = "localhost[10334]")属性从集群中获取其配置,这是通过将以下Cache bean定义添加到我们的内部静态useClusterConfiguration类,如下所示:

Configurer

现在,当我们再次运行我们的Spring Boot,Apache Geode对等GeodeConfiguration应用程序时,我们将看到完全不同的输出。首先,看到我们的对等成员(应用程序)获得了集群配置...

@Bean
PeerCacheConfigurer useClusterConfigurationConfigurer() {
  return (beanName, cacheFactoryBean) -> cacheFactoryBean.setUseClusterConfiguration(true);
}

接下来,您可能已经注意到,我使用SDG的Cache注释启用了PDX。这使我们可以轻松地序列化我们的应用程序域模型对象类型(例如<?xml version="1.0" encoding="UTF-8" standalone="no"?> <cache xmlns="http://geode.apache.org/schema/cache" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" copy-on-read="false" is-server="false" lock-lease="120" lock-timeout="60" search-timeout="300" version="1.0" xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd"> <region name="Customers"> <region-attributes data-policy="partition"> <key-constraint>java.lang.Long</key-constraint> <value-constraint>java.lang.Object</value-constraint> </region-attributes> </region> </cache> ),而我们的类型不需要过度实现@EnablePdx。有几个原因导致您不一定要实现Customer。使用SDG的java.io.Serializable使用SDG的MappingPdxSerializer实现,甚至比Apache Geode / Pivotal GemFire自己的java.io.Serializable更强大。

序列化应用程序类型(即@EnablePdx)的结果是,您将看到此输出...

ReflectionBasedAutoSerializer

启用PDX的另一个原因是,我不需要将Customer类添加到使用 Gfsh 开始的服务器(即“ 14:26:48.322 [main] INFO org.apache.geode.internal.cache.PartitionedRegion - Partitioned Region /Customers is created with prId=2 Started ClusterConfiguredGeodeServerApplication in 4.223 seconds (JVM running for 5.574) 14:26:48.966 [main] INFO org.apache.geode.pdx.internal.PeerTypeRegistration - Adding new type: PdxType[dsid=0, typenum=14762571 name=example.app.spring.cluster_config.server.ClusterConfiguredGeodeServerApplication$Customer fields=[ id:Object:identity:0:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=-1 name:String:1:1:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=1]] 14:26:49.002 [main] INFO org.apache.geode.pdx.internal.TypeRegistry - Caching PdxType[dsid=0, typenum=14762571 name=example.app.spring.cluster_config.server.ClusterConfiguredGeodeServerApplication$Customer fields=[ id:Object:identity:0:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=-1 name:String:1:1:idx0(relativeOffset)=0:idx1(vlfOffsetIndex)=1]] ”)中。它还使我可以查询“客户”区域,并看到成功添加了Customer“乔恩·多伊” ...

ServerOne

宾果!成功!

我什至不会开始讨论您的配置有问题的所有内容。我恳请您read the docs(和Apache Geode的User Guide;即相应的部分),理解概念,查看examplesguides,提出简洁的问题等。

这是示例源代码...

https://github.com/jxblum/contacts-application/blob/master/configuration-example/src/main/java/example/app/spring/cluster_config/server/ClusterConfiguredGeodeServerApplication.java

希望这会有所帮助!

-j