哪建设网站,中铁建设集团有限公司华南分公司,网站建设文献综述知乎,ui设计培训班是坑吗mongodb实验报告介绍 我使用Dropwizard#xff0c;MongoDB和Gradle创建了一个小项目。 它实际上是作为一个实验性的Guava缓存开始的#xff0c;作为将计数器发送到MongoDB#xff08;或任何其他DB#xff09;的缓冲区。 我也想尝试MondleDB插件的Gradle。 接下来#xff0… mongodb实验报告 介绍  我使用DropwizardMongoDB和Gradle创建了一个小项目。 它实际上是作为一个实验性的Guava缓存开始的作为将计数器发送到MongoDB或任何其他DB的缓冲区。 我也想尝试MondleDB插件的Gradle。 接下来我想创建某种界面来检查此框架因此我决定尝试使用DropWizard。 这就是这个项目的创建方式。   本文不是使用任何选定技术的教程。 这是一个小展示柜我做过实验。 我猜有一些缺陷也许我没有使用所有“最佳实践”。 但是我确实相信在本文的帮助下该项目可以成为我使用的各种技术的良好起点。 我还尝试显示一些设计选择这些选择有助于实现SRP去耦内聚等。   我决定从用例描述及其实现方式开始。 之后我将解释我对GradleMongoDB和嵌入式和Dropwizard所做的工作。   在开始之前这里是源代码   https://github.com/eyalgo/CountersBuffering  用例带缓冲区的计数器  我们对服务器有一些输入请求。 在请求过程中我们选择用一些数据由某些逻辑决定“绘制”它。 有些请求将由Value-1绘制某些请求将由Value-2绘制等等。有些将根本不会绘制。 我们要限制绘画请求的数量每个绘画值。 为了有限制对于每个绘制值我们知道最大值但是还需要计算每个绘制值绘制请求的数量。 由于系统具有多个服务器因此计数器应由所有服务器共享。   延迟至关重要。 通常每个请求处理会得到4-5毫秒对于所有流程。不仅仅是绘画。 因此我们不希望增加计数器会增加延迟。 相反我们将保留一个缓冲区客户端将向缓冲区发送“增加”。 缓冲区将定期以“批量增量”增加存储库。   我知道可以直接使用Hazelcast或Couchbase或其他类似的快速内存数据库。 但是对于我们的用例那是最好的解决方案。   原理很简单   从属模块将调用服务以增加某个密钥的计数器  该实现为每个键保留一个计数器缓冲区  这是线程安全的  编写在单独的线程中进行  每次写入都会大量增加     柜台高级设计   缓冲  对于缓冲区我使用了Google Guava 缓存 。   缓冲结构   创建缓冲区  private final LoadingCacheCounterable, BufferValue cache;
...this.cache  CacheBuilder.newBuilder().maximumSize(bufferConfiguration.getMaximumSize()).expireAfterWrite(bufferConfiguration.getExpireAfterWriteInSec(), TimeUnit.SECONDS).expireAfterAccess(bufferConfiguration.getExpireAfterAccessInSec(), TimeUnit.SECONDS).removalListener((notification) - increaseCounter(notification)).build(new BufferValueCacheLoader());
...  可逆的描述如下   BufferValueCacheLoader实现了CacheLoader接口。 当我们调用增加见下文时我们首先通过键从缓存中获取。 如果键不存在则加载器返回值。   BufferValueCacheLoader  public class BufferValueCacheLoader extends CacheLoaderCounterable, BufferValue {Overridepublic BufferValue load(Counterable key) {return new BufferValue();}
} BufferValue包装一个AtomicInteger 在某些时候我需要将其更改为Long   增加柜台   增加计数器如果超过阈值则发送  public void increase(Counterable key) {BufferValue meter  cache.getUnchecked(key);int currentValue  meter.increment();if (currentValue  threashold) {if (meter.compareAndSet(currentValue, currentValue - threashold)) {increaseCounter(key, threashold);}}
} 当增加一个计数器时我们首先从缓存中获取当前值在加载程序的帮助下。如上所述。 compareAndSet将自动检查是否具有相同的值未被另一个线程修改。 如果是这样它将更新该值并返回true。 如果成功返回true则缓冲区调用更新程序。   查看缓冲区   开发服务之后我想要一种查看缓冲区的方法。 因此我实现了以下方法该方法由前端层Dropwizard的资源使用。 Java 8 Stream和Lambda表达式的小示例。   获取所有计数器在缓存中  return ImmutableMap.copyOf(cache.asMap()).entrySet().stream().collect(Collectors.toMap((entry) - entry.getKey().toString(),(entry) - entry.getValue().getValue()));MongoDB  我之所以选择MongoDB是因为两个原因   我们的系统中有类似的实现我们决定在那里也使用MongoDB。  易于与嵌入式服务器一起使用。   我试图设计系统以便可以选择其他任何持久性实现并进行更改。   我使用吗啡作为MongoDB客户端层而不是直接使用Java客户端。 使用Morphia您可以创建dao 它是与MongoDB集合的连接。 您还声明了一个简单的Java BeanPOJO它表示集合中的文档。 一旦有了dao就可以使用相当简单的API以“ Java方式”对集合进行操作。 您可以查询和其他任何CRUD操作以及更多。   我有两个操作增加计数器和获取所有计数器。 服务实现不扩展Morphia的BasicDAO而是具有一个继承它的类。 我使用了组合 过度继承因为我希望两种服务都具有更多的行为。   为了与键表示保持一致并从依赖代码中隐藏其实现方式我使用了一个接口可通过单个方法counterCount来 抵消 。  public interface Counterable {String counterKey();
} DAO是服务内部的组成部分  final class MongoCountersDao extends BasicDAOCounter, ObjectId {MongoCountersDao(Datastore ds) {super(Counter.class, ds);}
} 增加柜台   MongoCountersUpdater扩展了实现CountersUpdater的AbstractCountersUpdater  Override
protected void increaseCounter(String key, int value) {QueryCounter query  dao.createQuery();query.criteria(id).equal(key);UpdateOperationsCounter ops  dao.getDs().createUpdateOperations(Counter.class).inc(count, value);dao.getDs().update(query, ops, true);
}嵌入式MongoDB  为了在持久层上运行测试我想使用内存数据库。 有一个MongoDB插件。 使用此插件您可以通过仅在运行时创建服务器来运行服务器或者在Gradle中的maven / task中作为目标运行。   https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo  https://github.com/sourcemuse/GradleMongoPlugin   Gradle上的嵌入式MongoDB   稍后我将详细介绍Gradle但这是设置嵌入式mongo所需的操作。  dependencies {// More dependencies heretestCompile com.sourcemuse.gradle.plugin:gradle-mongo-plugin:0.4.0
} 设置属性  mongo {//	logFilePath: The desired log file path (defaults to embedded-mongo.log)logging consolemongoVersion PRODUCTIONport 12345//	storageLocation: The directory location from where embedded Mongo will run, such as /tmp/storage (defaults to a java temp directory)
} 嵌入式MongoDB Gradle任务   startMongoDb只会启动服务器。 它将运行直到停止它。  stopMongoDb将停止它。  startManagedMongoDb test 这两个任务将在测试运行之前启动嵌入式服务器。 jvm完成测试完成后服务器将关闭    尽管我只触碰到冰山一角但我开始看到Gradle的力量。 设置项目甚至都不是那么困难。   Gradle设置   首先我在eclipse中创建了Gradle项目安装插件后。 我需要设置依赖项。 很简单。 就像行家一样。   一个大的JAR输出   当我想从Maven中的所有库中创建一个大jar时我会使用shade插件。 我在寻找类似的东西并发现gradle-one-jar插入。 https://github.com/rholder/gradle-one-jar我添加了该插件apply plugin: gradle-one-jar 。 在类路径中添加了一个jar  buildscript {repositories { mavenCentral() }dependencies {classpath com.sourcemuse.gradle.plugin:gradle-mongo-plugin:0.4.0classpath com.github.rholder:gradle-one-jar:1.0.4}
} 并添加了一个任务  mainClassName  org.eyalgo.server.dropwizard.CountersBufferApplication
task oneJar(type: OneJar) {mainClass  mainClassNamearchiveName  counters.jarmergeManifestFromJar  true
} 这些是我需要执行的必要操作才能使应用程序运行。  Dropwizard  Dropwizard是一堆库可以轻松快速地创建Web服务器。 它将Jetty用于HTTP将Jersey用于REST。 它具有其他成熟的库来创建复杂的服务。 它可以用作易于开发的微服务。   正如我在简介中所解释的我不会介绍Dropwizard的所有功能和/或设置。 有很多的网站。 我将简要介绍为使应用程序运行而执行的操作。   Gradle运行任务  run { args server, ./src/main/resources/config/counters.yml } 第一个参数是服务器。 第二个参数是配置文件的位置。 如果不将Dropwizard作为第一个参数则会收到有关可能选项的错误消息。  positional arguments:{server,check}         available commands 我已经在Gradle部分中展示了如何创建一个jar。   组态   在Dropwizard中您可以使用扩展Configuration的类来设置应用程序。 类中的字段应与yml配置文件中的属性对齐。   优良作法是根据属性的用途/职责将其分组。 例如我为mongo参数创建了一个组。   为了使配置类正确读取子组您需要创建一个与组中的属性对齐的类。   然后在主配置中将该类添加为成员并使用批注进行标记 JsonProperty 。   例  JsonProperty(mongo)
private MongoServicesFactory servicesFactory  new MongoServicesFactory();
JsonProperty(buffer)
private BufferConfiguration bufferConfiguration  new BufferConfiguration(); 示例更改端口   这是配置文件的一部分用于设置应用程序的端口。  server:adminMinThreads: 1adminMaxThreads: 64applicationConnectors:- type: httpport: 9090adminConnectors:- type: httpport: 9091健康检查  Dropwizard提供了开箱即用的基本管理API。 我将端口更改为9091。我为MongoDB连接创建了运行状况检查。 您需要扩展HealthCheck并实施检查方法。  private final MongoClient mongo;
...
protected Result check() throws Exception {try {mongo.getDatabaseNames();return Result.healthy();} catch (Exception e) {return Result.unhealthy(Cannot connect to   mongo.getAllAddress());}
} 其他功能几乎是不言自明的或者像任何入门教程一样简单。  增强想法  这些是我可能会尝试添加的内容。   将测试添加到Dropwizard部分。  该项目以PoC开头因此与往常不同我跳过了服务器部分中的测试。  Dropwizard拥有“ 测试Dropwizard” 我想尝试一下。  不同的持久性实现。 couchbaseHazelcast。  使用Google Guice进行注射。 并借助它注入不同的持久性实现。   就这样。 希望有帮助。   源代码 https : //github.com/eyalgo/CountersBuffering  翻译自: https://www.javacodegeeks.com/2015/02/dropwizard-mongodb-and-gradle-experimenting.htmlmongodb实验报告