Скала, Акка-Http и MySQL - слишком медленно - PullRequest
0 голосов
/ 12 октября 2019

Я пытался подключить MySQL к своему коду scala-Akka. В методе получения у меня есть 3 URL, и для этих URL я реализовал простой счетчик посещений. Поэтому, когда я посещаю этот конкретный URL, я вставляю в таблицу строку, которая будет (URL, счетчик, его временная метка). Но я заметил, что это слишком медленно. Выполнение только 180 запросов за 10 секунд! Что я могу сделать, чтобы улучшить производительность? Пожалуйста помоги!

import akka.actor.{Actor, ActorLogging, ActorSystem, Props}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
import akka.http.scaladsl.server.Directives._
import akka.pattern.ask
import akka.stream.ActorMaterializer
import akka.util.Timeout

import scala.concurrent.duration._
import scala.io.StdIn
import java.sql.{Connection, DriverManager, PreparedStatement, Timestamp}
import java.time.{LocalDateTime, LocalTime}
import java.util.Date

import akka.http.javadsl.server.Route


object DBCP3 {


  final case class fetch1(param:String)
  val sql = "INSERT INTO URLInfo (url, time, count)" + "VALUES (?, ?, ?)"

  val url = "jdbc:mysql://127.0.0.1/url"
  val driver = "com.mysql.jdbc.Driver"
  val username = "root"
  val password = "SomePassword"


  Class.forName(driver)
  var connection = DriverManager.getConnection(url, username, password)
  val date = new Date




  private var number1: Int = 0
  private var number3: Int = 0
  private var number2: Int = 0

  def insertIntoDB(path: String, num: Int) = {
   val stm: PreparedStatement = connection.prepareStatement(sql)

    stm.setString(1, path)
    stm.setTimestamp(2, new Timestamp(date.getTime))
    stm.setInt(3, num)
    stm.execute()
  }

  class ActorA extends Actor with ActorLogging {
    def receive = {
      case fetch1(param) =>
        if(param=="path1") {
          number1+=1
          insertIntoDB("http://localhost:8080/path1",number1)
          context.sender() ! number1

        }
        if(param=="path2") {
          number2+=1

          insertIntoDB("http://localhost:8080/path2",number2)

          context.sender() ! number2
        }
        if(param=="path3") {
          number3+=1

          insertIntoDB("http://localhost:8080/path3",number3)

          context.sender() ! number3
        }

    }
  }

  def main(args: Array[String]) {
    implicit val system = ActorSystem("my-system")
    implicit val materializer = ActorMaterializer()
    implicit val executionContext = system.dispatcher
    implicit val timeout: Timeout = 1.seconds



    val actor1 = system.actorOf(Props[ActorA], "SimpleActor1")


    val route = concat(
      path("path1") {
        get {

          onComplete((actor1 ? fetch1("path1")).mapTo[Int])
          {
            number => complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, s"<h1>You visited $number times</h1>"))

          }
        }

      },


      path("path2") {
        onComplete((actor1 ? fetch1("path2")).mapTo[Int])
        {
          number => complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, s"<h1>You visited $number times</h1>"))

        }


      },

      path("path3") {

        onComplete((actor1 ? fetch1("path3")).mapTo[Int])
        {
          number => complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, s"<h1>You visited $number times</h1>"))

        }


      }
    )

    val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)
    println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
    StdIn.readLine() // let it run until user presses return
    val _ = bindingFuture
      .flatMap(_.unbind()) // trigger unbinding from the port
    connection.close()
  }
}

...