注意: 不幸的是这个问题已经关闭,但是如果有其他人提出同样的问题,我正试图维护它.
我一直在寻找在Scala中开发服务的良好解决方案,该服务将位于移动设备和现有Web服务之间.
目前可行的选项清单是:
那里可能有更多的选择.如何决定使用哪一个?什么是一个好的Scala中间件选择的特征(借口双关语;-).一方面,我想去Akka,因为它是TypeSafe Scala堆栈的一部分,但另一方面,像Finagle这样的东西有一组丰富的库,使管道变得如此简单.喷雾看起来很好用,很简单.
任何建议,见解或经验将不胜感激.我相信那里的某些人必须有一些经验,他们不介意分享.
更新:
我很乐意重新开启这个问题.这个问题的一个很好的答案将有助于新的Scalateers避免相关的陷阱.
更新2:
这些是我自问这个问题后的经验:
Finagle - 我用Finagle进行了一个项目,它坚如磐石.
喷雾 - 在我的最新项目中,我正在使用Spray,我非常高兴.最新版本基于Akka 2构建,您可以使用Spray-can库直接运行它,无需Web服务器.Spray是一组库,而不是框架,非常模块化.在了解喷雾:在阿卡视频REST给出了一个很好的概述,而这个博客在Cakesolutions显示了一个非常好的发展方式和结构.
更新3:
生活移动得非常快.如果你不停下来,偶尔环顾四周,你可能会错过它.- Ferris Bueller
这些天选择变得更加简单.在我的拙见中,Spray赢得了这场战斗.它被整合到Akka中,成为下一个Akka HTTP.我现在一直在使用Spray进行多个项目,并且可以诚实地说它是我遇到的奇妙和最好的支持软件.
这不能回答最初的问题,但至少可以说明为什么Spray在大多数情况下似乎是最佳选择.它非常灵活,无阻塞且非常稳定.它有客户端和服务器端库以及一个很棒的测试工具包.另外,请查看这些统计信息以了解性能:Web框架基准测试
我将使用Scala和Akka Actors开发新的HTTP/REST服务.
我有使用Play的经验,但我并不需要一个完整的Web框架.从我读到的,我认为Spray是一个合适的选择.在新到达的AKKA-HTTP之后,我的问题来自Spray的未来.
Spray项目是否会独立于Akka-HTTP项目而增长,还是两个项目将合并为一个Akka-HTTTP?
如果我开始用Spray开发,这有什么影响?另外我读到Play将集成AKKA-HTTP.所以我终于想知道是不是应该选择Play?
谢谢你的帮助.
当我尝试在sbt中编译Scala项目时,我收到此错误.
Modules were resolved with conflicting cross-version suffixes in {file:/home/seven3n/caja/Flujo_de_caja/}flujo_de_caja:
[error] com.typesafe.akka:akka-actor _2.11, _2.10
[error] org.scalaz:scalaz-effect _2.10, _2.11
[error] org.scalaz:scalaz-core _2.10, _2.11
[trace] Stack trace suppressed: run last *:update for the full output.
[error] (*:update) Conflicting cross-version suffixes in: com.typesafe.akka:akka-actor, org.scalaz:scalaz-effect, org.scalaz:scalaz-core
Run Code Online (Sandbox Code Playgroud)
这是我的build.sbt文件:
scalaVersion := "2.11.0"
resolvers ++= Seq(
"Sonatype snapshots repository" at "https://oss.sonatype.org/content/repositories/snapshots/",
"Spray repository" at "http://repo.spray.io/",
"Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
)
libraryDependencies ++= {
val akkaVersion = "2.3.2"
val sprayVersion = "1.3.1-20140423"
val sprayJsonVersion = "1.2.6" …
Run Code Online (Sandbox Code Playgroud) 我正在调用API,但大多数情况下我一直收到错误:" 自SSL连接已关闭后删除关闭 "和" 过早连接关闭(服务器似乎不支持请求流水线)". "就像90%的时间我得到了这个错误,这意味着:在非常罕见的情况下,查询会返回它应该的数据.
为了确保这不是API的服务器问题,我使用Node.js(Express和Request libs)复制相同的查询,并且它每次都有效.这让我几乎可以肯定是一个喷雾虫.
这是代码的示例:
case class MyClass(user: String, pass: String)
class MyActor extends Actor {
import spray.client.pipelining._
import spray.http.BasicHttpCredentials
import spray.http.{HttpRequest,HttpResponse}
import scala.concurrent.Future
import context.dispatcher
def receive = {
case myClass: MyClass => {
val credentials: BasicHttpCredentials = BasicHttpCredentials(myClass.user, myClass.pass)
val url: String = "https://myApi?params=values"
val request: HttpRequest = Get(url) ~> addCredentials(credentials)
val pipeline = sendReceive
val response: Future[HttpResponse] = pipeline(request)
val finalRes: Future[String] = response.map{ r =>
println(r)
r.entity.asString
}
finalRes pipeTo …
Run Code Online (Sandbox Code Playgroud) 我正在考虑如何将我已经在本地测试过的rest api部署到云端的流程,让我们说基础架构即服务(不像像Heroku这样的服务平台)就像亚马逊一样.
我的本地环境设置已经启动并运行但我的问题是我应该如何在生产环境中部署它?
定义一个进程,其中devops从git repo中提取最新的更改然后只执行sbt run是否合理?
我想知道使用scala + spray + sbt的团队如何将他们的api部署到生产环境中.
在过去的几个月里,我和我的同事已经成功构建了一个服务器端系统,用于向iPhone设备发送推送通知.基本上,用户通过RESTful webservice(Spray-Server,最近更新为使用Spray-can作为HTTP层)注册这些通知,并且逻辑使用Akka的调度程序调度一个或多个消息以便将来调度.
这个系统,正如我们构建的那样,简单地工作:它可以每秒处理数百甚至数千个HTTP请求,并且可以以每秒23,000的速率发送通知 - 如果我们减少日志输出,可能会更多,添加多个通知发送方actor(以及与Apple的更多连接),并且可能在我们使用的Java库(java-apns)中进行一些优化.
这个问题是关于如何做对的(tm).我的同事,更了解Scala和基于演员的系统,注意到应用程序不是一个"纯粹的"基于演员的系统 - 他是对的.我现在想知道的是如何正确地做到这一点.
目前,我们有一个Spray HttpService
actor,而不是子类,用一组指令来初始化,这些指令概述了我们的HTTP服务逻辑.目前,非常简化,我们有这样的指令:
post {
content(as[SomeBusinessObject]) { businessObject => request =>
// store the business object in a MongoDB back-end and wait for the ID to be
// returned; we want to send this back to the user.
val businessObjectId = persister !! new PersistSchedule(businessObject)
request.complete("/businessObject/%s".format(businessObjectId))
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我做对了,那么来自演员的'等待回应'就是基于演员的编程中的禁忌(加上!!已被弃用).我认为"正确"的方法是将request
对象传递persister
给消息中的actor,并在request.complete
从后端收到生成的ID后立即调用它.
我已经在我的应用程序中重写了其中一条路线来做这件事; 在发送给actor的消息中,还发送请求对象/引用.这看起来像是应该的:
content(as[SomeBusinessObject]) { businessObject => request =>
persister ! new …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Java JTDS驱动程序连接到Scala中的数据库.但是,每当我尝试使用它时,我都会收到错误的版本(java?)错误.
java.lang.UnsupportedClassVersionError:net/sourceforge/jtds/jdbcx/JtdsDataSource:不支持的major.minor版本51.0
object DaoDriverAdaptor {
import java.sql.{DriverManager, Connection}
private def loadDriver() {
try {
Class.forName("net.sourceforge.jtds.jdbcx.JtdsDataSource")
} catch {
case e: Exception => {
println("ERROR: Driver not available: " + e.getMessage)
throw e
}
}
}
Run Code Online (Sandbox Code Playgroud)
java版"1.6.0_35"Java(TM)SE运行时环境(版本1.6.0_35-b10-428-11M3811)Java HotSpot(TM)64位服务器VM(版本20.10-b01-428,混合模式)
我正在使用scala,spray和akka来完成我的一个项目.在Intellij,它工作正常.当我构建项目并尝试在命令行中运行它时,我收到以下错误.
Caused by: com.typesafe.config.ConfigException$Missing: No configuration setting
found for key 'akka'
at com.typesafe.config.impl.SimpleConfig.findKey(SimpleConfig.java:124)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:147)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:159)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:164)
at com.typesafe.config.impl.SimpleConfig.getString(SimpleConfig.java:206)
at akka.actor.ActorSystem$Settings.(ActorSystem.scala:168)
at akka.actor.ActorSystemImpl.(ActorSystem.scala:504)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:141)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:108)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:99)
请帮我解决这个问题
我想使用spala支持以下路由实现一个简单的json REST服务器:
GET /foo => return a list of case class objects in json format
POST /bar => read a json into a case class object and perform some computation
Run Code Online (Sandbox Code Playgroud)
我的基本入门代码如下:
import spray.routing.SimpleRoutingApp
import spray.can.Http
import akka.actor.ActorSystem
import akka.actor.Props
import akka.io.IO
import scala.collection.JavaConversions
import com.fasterxml.jackson.databind.ObjectMapper
object SprayTest extends App with SimpleRoutingApp {
implicit val system = ActorSystem("my-system")
val mapper = new ObjectMapper
case class Foo(a: String, b: Int)
case class Bar(c: Long, d: String)
startServer(interface = "localhost", port = 8080) …
Run Code Online (Sandbox Code Playgroud) 我还没有找到一个可靠的示例或结构来将Spray.io路由分成多个文件.我发现我的路由的当前结构将变得非常麻烦,并且很好地将它们抽象到不同的"控制器"中以获得非常简单的REST API应用程序.
文档似乎没有太多帮助:http://spray.io/documentation/spray-routing/key-concepts/directives/#directives
这是我到目前为止所拥有的:
class AccountServiceActor extends Actor with AccountService {
def actorRefFactory = context
def receive = handleTimeouts orElse runRoute(demoRoute)
def handleTimeouts: Receive = {
case Timeout(x: HttpRequest) =>
sender ! HttpResponse(StatusCodes.InternalServerError, "Request timed out.")
}
}
// this trait defines our service behavior independently from the service actor
trait AccountService extends HttpService {
val demoRoute = {
get {
path("") {
respondWithMediaType(`text/html`) { // XML is marshalled to `text/xml` by default, so we simply override …
Run Code Online (Sandbox Code Playgroud)