如何使用 AKKA-HTTP、spray-json、oauth2 和 slick 优化 scala REST api?
Posted
技术标签:
【中文标题】如何使用 AKKA-HTTP、spray-json、oauth2 和 slick 优化 scala REST api?【英文标题】:How to optimize scala REST api using AKKA-HTTP, spray-json, oauth2 and slick? 【发布时间】:2017-01-31 11:11:31 【问题描述】:我使用AKKA-HTTP
、spray-json
和Slick
在scala 中创建了一个REST api。对于路由授权,我使用了oauth2
。
DAO 检索数据(使用普通 SQL):
def getAllNotes: Future[Seq[UserEntity]] =
implicit val getUserResult = GetResult(r => UserEntity(r.<<, r.<<, r.<<, r.<<, r.<<, r.<<))
query(s"select id, email, password,created_at, updated_at, deleted_at from users", getUserResult)
DAO 检索数据(Slick Table):
def getAll(): Future[Seq[A]] =
db.run(tableQ.result)
下面是路由部分:
val route: Route = pathPrefix("auth")
get
path("tests")
complete(userDao.getAll.map(u => u.toList))
~
path("test")
complete(userDao.getAllNotes.map(u => u.toList))
~
path("testUsers")
baseApi(userDao.getAllNotes)
~
path("users")
baseApi(userDao.getAll())
implicit def baseApi(f: ToResponseMarshallable): Route =
authenticateOAuth2Async[AuthInfo[OauthAccount]]("realm", oauth2Authenticator) auth =>
pathEndOrSingleSlash
complete(f)
从功能上讲,所有路由都按预期工作,但是当使用 OAUTH2 和 Slick Tables 获取数据时,性能似乎有所下降。
以上路线的各自结果:
1. "users" => 10 request per second: OAUTH2: YES, Slick Table: YES
2. "testUsers" => 17 request per second: OAUTH2: YES, Slick Table: NO
3. "tests" => 500 request per second: OAUTH2: NO, Slick Table: YES
4. "test" => 5593 request per second: OAUTH2: NO, Slick Table: NO
我的问题
如何使用 OAUTH2 和 Slick Table 优化 REST 请求?
如果我在所有情况下都使用 PLAIN SQL 而不是 Slick 表和联接,这会是一种好习惯吗?
【问题讨论】:
【参考方案1】:似乎启用 Oauth2 的影响最大,但是与在 oauth2Authenticator 上完成的网络/服务调用相比,akka http 增加的开销可以忽略不计。即使以异步方式完成,您仍然需要正确配置执行上下文(好读 Explaining AKKA Thread Pool Execturor Config parameters)。
关于 Slick 部分,您似乎在每个请求上声明了隐式行映射器(可以是类 val 属性)。 查看Compiled Queries 并确保在您的db 连接池配置中分配了足够的jdbc 连接。
无论如何,这个测试的整个概念似乎都不是很有用,应该有最低要求(例如:最少 100 个请求/秒),然后在此基础上开始构建。
【讨论】:
每个请求上的隐式行映射器,你的意思是userDao.getAll.map(u => u.toList)
。任何示例或代码 sn-p 都足以进行分析。 :)
我在getAllNotes
方法中引用了implicit val getUserResult
,可以改为在类级别声明。
我替换了隐式,我收到的成就是5926 rps
。我如何在getNotes()
中使用编译?我试过 db.run(Compiled(tableQ)) 但这会产生错误
在getAllNotes
中,您使用了一个带有字符串和行映射器的query
函数,我假设您在其中使用db.run(sql(plainQuery))
之类的东西,因为您的查询没有参数,您可以还在类级别将其声明为 val notesQuery=Compile(sql"select .. from users")) 然后在 getAllNotes
中使用 db.run(notesQuery)
...
你对Scala中的OAuth2有什么其他的实现思路【参考方案2】:
关于Slick
的部分已被多次回答。最新答案在这里:Cache Slick DBIO Actions
这应该会显着缩短普通 Slick
版本的响应时间。
虽然OAUTH2
无法帮助您:/
【讨论】:
以上是关于如何使用 AKKA-HTTP、spray-json、oauth2 和 slick 优化 scala REST api?的主要内容,如果未能解决你的问题,请参考以下文章
使用 akka-http 模板的新 sbt 应用程序,如何确定解析器并添加 maven Central?