java.security.Security.setProperty("networkaddress.cache.ttl" , "0") private static CloseableHttpClient httpClient;
static {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(20);
cm.setDefaultMaxPerRoute(50);
httpClient = HttpClients.custom().setConnectionManager(cm).build();
}
● 代码中设置JVM的DNS域名缓存时间为1秒。
java.security.Security.setProperty("networkaddress.cache.ttl" , "1");
● 如果需要考虑扩容后不重启应用能够识别出新的IP地址,可以考虑设置连接的 TTL,但是对性能会有一点影响。
HttpClients.custom().setConnectionTimeToLive(600, TimeUnit.SECONDS);
OS 优化
● Linux操作系统关闭本地DNS域名解析缓存。检查/etc/init.d/目录下是否有nscd 或 者 named 或者 dnsmasq,如果存在,分别执行如下命令关闭缓存。
/etc/init.d/nscd stop /etc/init.d/named stop /etc/init.d/dnsmasq stop
● Windows操作系统关闭本地DNS域名解析缓存。在cmd中执行如下命令。
net stop dnscache
5 开发 GeoMesa 应用
5.1 典型场景说明
通过典型场景,我们可以快速学习和掌握GeoMesa的开发过程,并且对关键的接口函 数有所了解。
场景说明
假定用户开发一个应用程序,用于记录和查询其与朋友见面约会信息:与谁在什么时 间什么地点做了什么,记录数据格式如表:
字段名称 字段类型
Who String
What Long
When Date
Where Point
Why String
5.2 开发思路
根据上述的业务场景进行功能分解,需要开发的功能点如表:
序号 步骤 代码实现
1 连接GeoMesa集群 请参见创建DataStore。
2 创建数据表 请参见创建数据表。
3 插入数据 请参见插入数据。
4 查询数据 请参见查询数据。
5.3 样例代码说明
5.3.1 配置参数
步骤1 执行样例代码前,必须在hbase-site.xml配置文件中,配置正确的ZooKeeper集群的地 址。
配置项如下:
<property>
<name>hbase.zookeeper.quorum</name>
<value>xxx-zk1.cloudtable.com,xxx-zk2.cloudtable.com,xxx-zk3.cloudtable.com</value>
</property>
其中:value中的值为ZooKeeper集群的域名。登录表格存储服务管理控制台,在左侧 导航树单击“集群模式”,然后在集群列表中找到所需要的集群,并获取相应的“ZK 链接地址”。
----结束
5.3.2 创建 DataStore
功能简介
使用GeoMesa的接口连接GeoMesa集群创建DataStore,DataStore实例提供可对 GeoMesa指定目录操作的接口。
样例代码
// find out where -- in HBase -- the user wants to store data CommandLineParser parser = new BasicParser();
Options options = getCommonRequiredOptions();
CommandLine cmd = parser.parse(options, new String[]{"--bigtable_table_name", "geomesa"});
// verify that we can see this HBase destination in a GeoTools manner Map<String, Serializable> dsConf = getHBaseDataStoreConf(cmd);
DataStore dataStore = DataStoreFinder.getDataStore(dsConf);
5.3.3 创建数据表
功能简介
在指定目录的DataStore中创建数据表。
样例代码
// establish specifics concerning the SimpleFeatureType to store String simpleFeatureTypeName = "QuickStart";
// list the attributes that constitute the feature type
String attributes = "Who:String,What:java.lang.Long,When:Date,*Where:Point:srid=4326,Why:String";
// create the bare simple-feature type
SimpleFeatureType simpleFeatureType = SimpleFeatureTypes.createType(simpleFeatureTypeName, attributes);
dataStore.createSchema(simpleFeatureType);
5.3.4 插入数据
功能介绍
构造数据并将数据插入到指定表中。
样例代码
DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
String id;
Object[] NO_VALUES = {};
String[] PEOPLE_NAMES = {"Addams", "Bierce", "Clemens"};
Long SECONDS_PER_YEAR = 365L * 24L * 60L * 60L;
Random random = new Random(5771);
DateTime MIN_DATE = new DateTime(2014, 1, 1, 0, 0, 0, DateTimeZone.forID("UTC"));
Double MIN_X = -79.5;
Double MIN_Y = 37.0;
Double DX = 2.0;
Double DY = 2.0;
for (int i = 0; i < numNewFeatures; i++) {
// create the new (unique) identifier and empty feature shell id = "Observation." + Integer.toString(i);
SimpleFeature simpleFeature = SimpleFeatureBuilder.build(simpleFeatureType, NO_VALUES, id);
// be sure to tell GeoTools explicitly that you want to use the ID you provided simpleFeature.getUserData().put(Hints.USE_PROVIDED_FID, java.lang.Boolean.TRUE);
// populate the new feature's attributes // Who: string value
simpleFeature.setAttribute("Who", PEOPLE_NAMES[i % PEOPLE_NAMES.length]);
// What: long value
simpleFeature.setAttribute("What", i);
// Where: location: construct a random point within a 2-degree-per-side square double x = MIN_X + random.nextDouble() * DX;
double y = MIN_Y + random.nextDouble() * DY;
Geometry geometry = WKTUtils$.MODULE$.read("POINT(" + x + " " + y + ")");
simpleFeature.setAttribute("Where", geometry);
// When: date-time:construct a random instant within a year
DateTime dateTime = MIN_DATE.plusSeconds((int) Math.round(random.nextDouble() * SECONDS_PER_YEAR));
simpleFeature.setAttribute("When", dateTime.toDate());
// Why: another string value
// left empty, showing that not all attributes need values // accumulate this new feature in the collection
featureCollection.add(simpleFeature);
FeatureStore featureStore = (FeatureStore) dataStore.getFeatureSource(simpleFeatureTypeName);
featureStore.addFeatures(featureCollection);
}
5.3.5 查询数据
功能简介
根据指定时空条件查询数据。
样例代码
// construct a (E)CQL filter from the search parameters, // and use that as the basis for the query
Filter cqlFilter = createFilter(geomField, x0, y0, x1, y1, dateField, t0, t1, attributesQuery);
Query query = new Query(simpleFeatureTypeName, cqlFilter);
List<String> properties = new LinkedList<>();
// submit the query, and get back an iterator over matching features
FeatureSource featureSource = dataStore.getFeatureSource(simpleFeatureTypeName);
FeatureCollection featureCollection = featureSource.getFeatures(query);
FeatureIterator featureItr = featureCollection.features();
// loop through all results int n = 0;
while (featureItr.hasNext()) { Feature feature = featureItr.next();
feature.getIdentifier().getID();
System.out.println((++n) + "." +
feature.getProperty("Who").getValue() + "|" + feature.getProperty("What").getValue() + "|" + feature.getProperty("When").getValue() + "|" + feature.getProperty("Where").getValue() + "|" + feature.getProperty("Why").getValue());
}featureItr.close();