- Heroku - Servidor hosteado en Heroku.
- SBT - Build Tools
- Scala - Lenguaje
- Finagle - Platform Server
- TwitterServer - Server API.
- Activate - Framework de Persitencia
Tenemos un package object que tiene la configuracion de toda la aplicación. Muchas de esas configuraciones se leen de variables de entorno (aunque tienen un valor por default)
El objeto es:
package object configuration {
object environment {
val development
val heroku
val name
}
object server{
val port
}
object response{
val limitSize
val maxLimitSize
}
object database{
val storage
val fillData
object mongo {
val host
val port
val db
val authentication
}
object mysql{
val user
val password
val url
}
object redis{
val host
val port
}
}
}
Por default la app levanta en el puerto 9200
.
- Desde IntelliJ:
Para la ejecución hay que ejecutar el object
Server
. - Desde la consola:
Correr el comando
sbt run
y la app levanta. - Desde la consola generando un jar:
Correr el comando
sbt assembly
que generra el archivocarePrices.jar
. Una vez generado se puede correr el jar ejecutando:java -jar carePrices.jar
Por default el servidor va a escuchar el puerto 9200
.
Para cambiar eso hay que setear la variable de entorno correspondiente o modificar el puerto por default:
val port = ":" + Properties.envOrElse("PORT", "9200")
Para elegir que motor de base de datos se quiere usar hay que modificar la variable storage
:
val storage = Properties.envOrElse("storage", "transient")
Los valores posibles son:
transient
- Utiliza la memoriamysql
- Utiliza Mysqlmongo
- Utiliza MongoDB
Por default la base que utilizada es transient
.
Podemos elegir si queremos instanciar datos de prueba, puede ser para que cuando trabajemos en modo transient, tener datos en cada corrida o si elegimos alguna de las bases persistente para llenar la base con un pequeño set de datos.
Para cambiar esta configuracion hay que setear la variable fill_data
:
val fillData = Properties.envOrNone("fill_data").map(_=>false).getOrElse(true)
Si queremos que se utilice mysql
debemos configurar:
-
user
- Por default es root.val user = Properties.envOrSome("mysql_user", Some("root"))
--
-
password
- Por default es root.val password = Properties.envOrSome("mysql_pwd", Some("root"))
--
-
schema
- Aca se configura el Schema:val schema = Properties.envOrElse("mysql_schema", "careprices")
--
-
url
- Aca se configura Host:val url = Properties.envOrElse("mysql_url", "jdbc:mysql://localhost:8889/")
Las tablas las crea el software.
Si queremos utilizar mongo hay que configurar:
-
host
- Por default es localhost.val host = Properties.envOrElse("mongo_host", "localhost")
--
-
port
- Por default es 27017.val port = Properties.envOrElse("mongo_posts", "27017")
--
-
db
- Por default es careprices :val db = Properties.envOrElse("mongo_db", "careprices")
--
-
authentication
- Por default es None:val authentication = Properties.envOrNone("mongo_auth")
Estamos usando Redis como cache de algunos recursos. Todavia no esta muy bien definido hasta que tengamos mas avanzado el TP. Por ahora lo usamos en un solo servicio, el de precios. Si no hay un servidor de redis, no pasa nada, se ignora la chaché y se ejecuta el código original. Es decir si no tenemos un servicio de Redis la aplicación sigue funcionando.
Para utilizar Redis necesitamos configurar:
host
- Por default es localhost.val host = Properties.envOrElse("redis_host", "localhost")
port
- Por default es 6379.val port = Properties.envOrElse("redis_port", "6379")
Nuestra app corre en una imagen docker con las siguientes catacterísticas:
- Ubuntu 15.10
- Java 8
Estamos usando docker-compose
para describir algunas dependencias de imágenes:
- MongoDB
- Mysql
- Redis
Cada una de esas imágenes corre en un contenedor distinto que la app y se comunican por red. Lo que falta de configurar es pasar las variables de entorno de nuestra app para configurar la base de datos a utilizar.
Lo que no sabemos bien es si es mejor tener un contenedor por servicio o todos los servicios en el mismo contenedor/imagen.
Lavantar la imágen tenemos un script docker_run.sh
que compila las imágenes y las levanta.
Podemos configurar para que utilice la base de datos que querramos o si se quiere utilizar a redis como cache.
Las formas son:
docker_run.sh -d mysql
odocker_run.sh --database=mysql
- Con esto nuestra app utiliza mysql como base de datos.docker_run.sh -d mongo
odocker_run.sh --database=mongo
- Con esto nuestra app utiliza mongodb como base de datos.docker_run.sh -c redis
odocker_run.sh --cache=redis
- Con esto nuestra app utiliza redis como cache.- Tambien podemos combinar mysql con redis p mongo con redis:
docker_run.sh -d mongo -c redis
.
Tenemos integrado newrelic en la imagen de docker, para monitorear el server y en la app.
La información del server se encuentra en la sección Servers de newrelic.
La información de la aplicación se encuentra en la sección APM de newrelic con el nombre de Careprice (Developmnent)
.
Para el monitoreo de la aplicación tenemos dos integraciones:
-
El primero esta integrado al server container, que monotorea todo el estado de la app. Pero esta integración no es completa, muestra todas las transacciones en una, bajo el nombre de /NettyDispatcher (aparentemente es una limitación del framework elegido).
-
El segundo es utilizando la api de newrelic creamos un
filtro
para tracear todos los request y responses que realiza nuestra app.
Como contenido extra, tenemos mas info de el estado del servidor con una herramienta que de Finagle que esta levantada en el puerto 9990
.