restapi(9)- caching, akka-http 缓存
restapi作为前后端交互的枢纽:面对大批量的前端请求,需要确保回复的及时性。使用缓存是一项有效工具。我们可以把多数前端请求的回复response存入缓存,特别是一些需要大量计算才能获取的回复值,更可以大大提高后端的反应速度。值得庆幸的是akka-http已经提供了对缓存的支持,是基于java8 caffein的一套缓存操作工具包的。下面就介绍一下akka-http的caching。
akka-http caching 有个依赖:
"com.typesafe.akka" %% "akka-http-caching" % akkaHttpVersion,
先从缓存存储结构开始,看看下面的一段缓存结构定义:
import akka.http.scaladsl.util.FastFuture import akka.http.caching.scaladsl.Cache import akka.http.caching.scaladsl.CachingSettings import akka.http.caching.LfuCache val defaultCachingSettings = CachingSettings(sys) val lfuCacheSettings = //最少使用排除算法缓存 defaultCachingSettings.lfuCacheSettings .withInitialCapacity(128) //起始单位 .withMaxCapacity(1024) //最大单位 .withTimeToLive(1.hour) //最长存留时间 .withTimeToIdle(30.minutes) //最长未使用时间 val cachingSettings = defaultCachingSettings.withLfuCacheSettings(lfuCacheSettings) //key -> String val lfuCache: Cache[String, Option[Map[String, Any]]] = LfuCache(cachingSettings)
lfuCache是一种基于使用频率算法的缓存管理系统,这个我们就不必多说了。最好能拿个例子来示范解释:刚好手头有个获取用户信息的http请求样板:
val route = pathPrefix(pathName) { pathPrefix("getuserinfo") { (get & parameter('userid)) { userid => { val userinfo = posRepo.getUserInfo(userid) userinfo match { case Some(ui) => complete(toJson(ui)) case None => complete(toJson(Map[String, Any](("TERMINALID" -> "")))) } } } } def getUserInfo(userid: String): Option[UserInfo] = { val sql = "SELECT CUSTOMERS.SHOPID AS SHOPID, TERMINALID, DEVICEID, IMPSVCURL FROM CUSTOMERS INNER JOIN TERMINALS " + " ON CUSTOMERS.SHOPID=TERMINALS.SHOPID " + " WHERE (CUSTOMERS.DISABLED=0 AND TERMINALS.DISABLED=0) " + " AND (CUSTOMERS.EXPDATE > GETDATE() AND TERMINALS.EXPDATE > GETDATE()) AND TERMINALID='" + userid + "'" val rows = query[Map[String, Any]]("mpos", sql, rsc.resultSet2Map) val futUI: Future[Option[Map[String, Any]]] = rows.runWith(Sink.lastOption) Await.result(futUI, 3 seconds) }