mongodb实验报告_Dropwizard,MongoDB和Gradle实验

mongodb实验报告

介绍

我使用Dropwizard,MongoDB和Gradle创建了一个小项目。 它实际上是作为一个实验性的Guava缓存开始的,作为将计数器发送到MongoDB(或任何其他DB)的缓冲区。 我也想尝试MondleDB插件的Gradle。 接下来,我想创建某种界面来检查此框架,因此我决定尝试使用DropWizard。 这就是这个项目的创建方式。

本文不是使用任何选定技术的教程。 这是一个小展示柜,我做过实验。 我猜有一些缺陷,也许我没有使用所有“最佳实践”。 但是,我确实相信,在本文的帮助下,该项目可以成为我使用的各种技术的良好起点。 我还尝试显示一些设计选择,这些选择有助于实现SRP,去耦,内聚等。

我决定从用例描述及其实现方式开始。 之后,我将解释我对Gradle,MongoDB(和嵌入式)和Dropwizard所做的工作。

在开始之前,这里是源代码:

  • https://github.com/eyalgo/CountersBuffering

用例:带缓冲区的计数器

我们对服务器有一些输入请求。 在请求过程中,我们选择用一些数据(由某些逻辑决定)“绘制”它。 有些请求将由Value-1绘制,某些请求将由Value-2绘制,等等。有些将根本不会绘制。 我们要限制绘画请求的数量(每个绘画值)。 为了有限制,对于每个绘制值,我们知道最大值,但是还需要计算(每个绘制值)绘制请求的数量。 由于系统具有多个服务器,因此计数器应由所有服务器共享。

延迟至关重要。 通常,每个请求处理会得到4-5毫秒(对于所有流程。不仅仅是绘画)。 因此,我们不希望增加计数器会增加延迟。 相反,我们将保留一个缓冲区,客户端将向缓冲区发送“增加”。 缓冲区将定期以“批量增量”增加存储库。

我知道可以直接使用Hazelcast或Couchbase或其他类似的快速内存数据库。 但是对于我们的用例,那是最好的解决方案。

原理很简单:

  • 从属模块将调用服务以增加某个密钥的计数器
  • 该实现为每个键保留一个计数器缓冲区
  • 这是线程安全的
  • 编写在单独的线程中进行
  • 每次写入都会大量增加
柜台高级设计

柜台高级设计

缓冲

对于缓冲区,我使用了Google Guava 缓存 。

缓冲结构

创建缓冲区:

private final LoadingCache<Counterable, 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 CacheLoader<Counterable, 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是因为两个原因:

  1. 我们的系统中有类似的实现,我们决定在那里也使用MongoDB。
  2. 易于与嵌入式服务器一起使用。

我试图设计系统,以便可以选择其他任何持久性实现并进行更改。

我使用吗啡作为MongoDB客户端层,而不是直接使用Java客户端。 使用Morphia,您可以创建dao ,它是与MongoDB集合的连接。 您还声明了一个简单的Java Bean(POJO),它表示集合中的文档。 一旦有了dao,就可以使用相当简单的API以“ Java方式”对集合进行操作。 您可以查询和其他任何CRUD操作,以及更多。

我有两个操作:增加计数器和获取所有计数器。 服务实现不扩展Morphia的BasicDAO,而是具有一个继承它的类。 我使用了组合 (过度继承),因为我希望两种服务都具有更多的行为。

为了与键表示保持一致,并从依赖代码中隐藏其实现方式,我使用了一个接口:可通过单个方法counterCount()来 抵消

public interface Counterable {String counterKey();
}

DAO,是服务内部的组成部分:

final class MongoCountersDao extends BasicDAO<Counter, ObjectId> {MongoCountersDao(Datastore ds) {super(Counter.class, ds);}
}

增加柜台

MongoCountersUpdater扩展了实现CountersUpdater的AbstractCountersUpdater:

@Override
protected void increaseCounter(String key, int value) {Query<Counter> query = dao.createQuery();query.criteria("id").equal(key);UpdateOperations<Counter> 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 'console'mongoVersion 'PRODUCTION'port 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.0'classpath 'com.github.rholder:gradle-one-jar:1.0.4'}
}

并添加了一个任务:

mainClassName = 'org.eyalgo.server.dropwizard.CountersBufferApplication'
task oneJar(type: OneJar) {mainClass = mainClassNamearchiveName = 'counters.jar'mergeManifestFromJar = 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” ,我想尝试一下。
  • 不同的持久性实现。 (couchbase?Hazelcast?)。
  • 使用Google Guice进行注射。 并借助它注入不同的持久性实现。

就这样。 希望有帮助。

  • 源代码: https : //github.com/eyalgo/CountersBuffering

翻译自: https://www.javacodegeeks.com/2015/02/dropwizard-mongodb-and-gradle-experimenting.html

mongodb实验报告

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338080.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

历城职专学前计算机专业,历城职专学前教育专业2020学年第一学期技能运动会拉开帷幕...

原标题&#xff1a;历城职专学前教育专业2020学年第一学期技能运动会拉开帷幕技能运动会学前教育专业技能运动会1月13日&#xff0c;历城职专学前教育专业2020学年第一学期技能运动会拉开帷幕&#xff0c;技能运动会是历城职专对每一位职专学子专业技能考核的一项重要检测&…

guava集合操作类的使用_使用Guava进行测试集合的实现

guava集合操作类的使用我目前正在为LibFX添加一项新功能&#xff0c;为此我创建了一些类似于Java Collections Framework的自定义集合。 我一直在寻找可以与之对抗的测试&#xff0c;并很高兴发现Google的Guava包含了我所需要的&#xff1a;一个庞大的测试套件&#xff0c;可以…

如何正确认识C语言在当今编程领域的地位

点击上方蓝字关注我&#xff0c;了解更多咨询一、什么是语言&#xff0c;什么是C语言&#xff0c;有什么区别与联系&#xff1f;一提到语言这个词&#xff0c;人们自然想到的是像英语、汉语等这样的自然语言&#xff0c;因为它是人和人相互交流信息不可缺少的工具。大家听到我们…

三十学计算机编程,计算机学习三宗罪3——计算机达人成长之路(25)

6、论道(四)计算机学习三宗罪之偏科上文说道木鹏飞声明计算机学习的第二宗罪是学习浮躁&#xff0c;只流于表面而不肯深入底层学习&#xff0c;并指出了编程的三重境界。木鸿飞则继续咨询第三宗罪。“第三宗罪就是偏科。具体来讲有两种表现&#xff0c;一是动手编程和理论学习二…

fx 线程 弹窗_JFXPanel和FX Platform线程陷阱

fx 线程 弹窗JFXPanel是一个组件&#xff0c;可将JavaFX内容嵌入到&#xff08;旧版;-)&#xff09;Swing应用程序中。 基本上&#xff0c;这使合并两个对象变得非常容易&#xff0c;但是要掌握一些陷阱&#xff1a;两个UI工具箱都是单线程的&#xff08;Swing&#xff1a;EDT …

计算机操作系统的新技术新知识,计算机操作系统教程:核心与设计原理

计算机操作系统教程&#xff1a;核心与设计原理语音编辑锁定讨论上传视频《计算机操作系统教程——核心与设计原理》是2007年清华大学出版社出版的图书&#xff0c;作者是范策、许宪成、黄红桃。书 名计算机操作系统教程——核心与设计原理作 者范策许宪成黄红桃等ISBN97…

理解好内存管理,C语言就不难学了

点击上方蓝字关注我&#xff0c;了解更多咨询任何程序运行起来都需要分配内存空间存放该进程的资源信息的&#xff0c;C程序也不例外。C程序中的变量、常量、函数、代码等等的信息所存放的区域都有所不同&#xff0c;不同的区域又有不同的特性。C语言学习者、尤其是在学习嵌入式…

智伴机器人安卓怎么设置个人热点_周五到!!宿舍断网怎么办,教你一招

对于大学里喜欢上网的小伙伴们&#xff0c;一旦到了断网的时间段&#xff0c;非常的难受&#xff0c;今天小白教大家一招&#xff0c;看到最后&#xff01;&#xff01;以后断网再也不怕啦&#xff0c;熬夜伤身&#xff0c;慎用&#xff01;&#xff01;相信很多同学都知道了手…

netty socket_Netty:另一种Web(Socket)服务器

netty socket如今&#xff0c; Netty已用于Internet上的各种应用程序中&#xff0c;以处理数千个&#xff08;如果不是上百万个&#xff09;聊天对话&#xff0c;包括Minecraft &#xff0c; Twitter和许多其他应用程序在内的多人游戏。 但是&#xff0c;它并没有深入到开发企业…

计算机用户guest无法删除吗,Win7怎么删除Guest账户?

原标题&#xff1a;Win7怎么删除Guest账户&#xff1f;我们都知道&#xff0c;访客帐户是系统附带的帐户。通常&#xff0c;用户给出了访客帐户。为了确保系统的安全性&#xff0c;它是一个限制帐户。使用客人帐户&#xff0c;您有权临时使用我们的计算机。但是&#xff0c;一些…

为什么C语言不会过时?

点击上方蓝字关注我&#xff0c;了解更多咨询评价任何一门编程语言&#xff0c;都是招人骂的。永远是这样。就像是春寒料峭的季节&#xff0c; 街上穿棉袄和穿单衣的擦肩而过&#xff0c;双方一定是同时在心里出现了两个字&#xff1a;“傻逼&#xff01;”这个在心理学上有个专…

机械装备计算机控制技术考试题,武汉理工大学机电工程学院研究生课程考试试题(肖峻)...

武汉理工大学机电工程学院研究生课程考试试题课程名称 机械装备计算机控制技术Ⅱ一&#xff0e;简答题(合计30分&#xff0c;每题10分)1、计算机控制系统按系统结构和控制功能分为哪几种&#xff1f;分别描述其特点。2、简述几种常用的数字滤波方法及其优、缺点。如何选用各种数…

java 性能 优化_Java十大简单性能优化

java 性能 优化关于“ web scale ”这个流行词有很多炒作&#xff0c;人们花了很多时间来重新组织他们的应用程序体系结构&#xff0c;以使其系统“规模化”。 但是什么是扩展&#xff0c;我们如何确保可以扩展&#xff1f; 缩放的不同方面 上面提到的炒作主要是关于扩展负载…

cx_oracle写日志信息_看日志痛苦——可能是你方法不对

看日志&#xff0c;是研发的日常工作&#xff0c;相信你已经从各种报错日志中查出许多BUG&#xff0c;但也被冗长、复杂的日志困扰过无数次。在日常工作中&#xff0c;我也经常痛苦于看日志&#xff0c;一般是这些日志长得面目狰狞&#xff1a;日志文件太大&#xff0c;打开都很…

在Swift中使用C语言的指针

点击上方蓝字关注我&#xff0c;了解更多咨询Objective-C和C语言经常需要使用到指针。Swift中的数据类型由于良好的设计&#xff0c;使其可以和基于指针的C语言API无缝混用。同时 Swift也可以自动处理大多数将指针作为参数的情况。在这篇文章里&#xff0c;我们可以看到在Swift…

计算机四级数据库分值分布,计算机四级数据库工程师考试成绩查询注意事项

计算机四级数据库工程师考试成绩查询注意事项为帮助广大考生更好的了解有关计算机四级数据库工程师考试的相关信息&#xff0c;唯学小编特整理了计算机四级数据库工程师考试成绩查询注意事项&#xff0c;望考生能够认真查看。同时唯学小编特别提醒想要参加数据库工程师考试的考…

android 音频合成_【Android工具】用手机测量噪声的工具软件,噪声仪分贝计,量化噪声声音工具...

今天分享一个通过手机麦克风测量环境噪声的工具——声级计(噪声仪)。本来是要分享另一款的&#xff0c;但下载下来的是xapk的安装包&#xff0c;太麻烦了&#xff0c;功能差不多&#xff0c;大家就先用这款吧&#xff0c;有条件的朋友可以去play自己下载。软件名称&#xff1a;…

cassandra_Apache Cassandra和低延迟应用程序

cassandra介绍 多年来&#xff0c; Grid Dynamics拥有许多与NoSQL相关的项目&#xff0c;尤其是Apache Cassandra。 在这篇文章中&#xff0c;我们要讨论一个给我们带来挑战的项目&#xff0c;而我们在该项目中试图回答的问题今天也仍然适用。 数字营销和在线广告在2012年很受…

浅析五种C语言内存分配的方法及区别

点击上方蓝字关注我&#xff0c;了解更多咨询在C语言中&#xff0c;内存分成5个区&#xff0c;他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。栈&#xff0c;就是那些由编译器在需要的时候分配&#xff0c;在不需要的时候自动清楚的变量的存储区。里面的变量通常…

认识计算机听课记录20篇,【中学信息技术听课记录】 信息技术听课记录15篇及评析_初中信息技术听课记录_高中信息技术听课记录20篇_东城教研...

中学信息技术听课记录关于中学信息技术听课记录&#xff0c;东城教研小编了解到&#xff1a;听课记录表(一)实习学校&#xff1a;_xxx九年制学校__ 实践基地任课教师:xxx 班 级 八、一 时 间 2014.12.22 授课人 xxx 授课题目 软件的下载与安装 类 型 新授 教学过程 内 容 说 明…