2013-03-12 34 views
13

Scala uygulamalarını uzak Linux sunucusunda dağıtmanın tercih edilen yolu nedir.Scala uygulamalarını uzak sunucuda dağıtma, başlatma ve durdurma

Bu uzak bir sunucuda bir Scala uygulamayı dağıtmaya oldukça basit ama sınırlı, yolu (-so duyarlı değildir projelerin hızlı test için güzel): Ben çekme uzak sunucuya itibaren

  1. benim Kullanımı git
  2. kaynak sbt-assembly eklenti sunucuda bir kavanoz inşa
  3. Ben o zaman işlem sonlandırılıyor olmadan uzak oturumu çıkmak için izin verir nohup kullanarak Scala uygulamasını çalıştırın:

    nohup java-jar myapp.jar> myapp.log 2> myapp.err </dev/null &

İlk olarak, kaynak kullanıyor göz önüne alındığında, çalışmaya başladıktan sonra işlemini durdurmak için en iyi yolu nedir Veritabanları vb. gibi. Sadece java işlem kimliğini arar mı ve nükleer mi? İkinci olarak, bir java uygulamasını yeniden başlatıldığında otomatik olarak başlatmanın en iyi yolu nedir? Geçmişte init.d kullanmayı hatırlıyorum, ama bir java uygulaması olduğu için yokuş yukarı gitmeyi unutmayın.

Güncelleme:

burada odadaki fili kaçırdı. Sırayla Akka'yı kullanan Sprey kütüphanesini kullanıyorum, bu sayede birçok ilginç seçenek sunuyor.

+0

Uygulamayı hizmet olarak yükleme veya TCP soketiyle kapatma iletisi gönderme hakkında ne düşünüyorsunuz? –

+0

Herhangi bir zamanda bir işlemi durdurma gereksiniminizle ilgili olarak, 'screen' kullanılmasını öneririm ve jar'ınızı ekran oturumunda çalıştırırım. Bir pencereyi ve içinde çalışan işlemleri öldürmek için 'ctrl + a k' kullanın. – Kane

+0

Teşekkür ederiz @Kane. Bunu unutmuştum. Bu harika bir fikir, özellikle ekranları diğer geliştiricilerle paylaşabildiğiniz için (eğer bellek bana uygunsa) – Jack

cevap

17

taşıdık olabilir Muhtemel http://evgeny-goldin.com/wiki/Sshexec-maven-plugin

...

Sen basit ini içinde https://github.com/sbt/sbt-start-script hatta sbt-yerli-packager https://github.com/sbt/sbt-native-packager

Sen sprey en Boot örnek senaryosunu sarabilirdiniz sbt-start-script kullanabilirsiniz t.d betiği bu yanıtı https://stackoverflow.com/a/17399574/155689 numaralı telefondan ya da sadece nohup java komutunu kullanarak çağırır.

Daha büyük bir programla ilgili sınıfları ve komut dosyalarını oluşturabilir veya Jsvc http://commons.apache.org/proper/commons-daemon/jsvc.html veya Java Service Wrapper kullanan init.d komut dosyaları ile genişletebilirsiniz.http://wrapper.tanukisoftware.com/

bir cin ve uygulama sınıfının bir örneği:

package com.example.myapplication.server 

import akka.actor.{Props, ActorSystem} 
import spray.can.Http 
import akka.io.IO 
import com.example.myapplication.api.MyServiceActor 
import org.apache.commons.daemon._ 

trait ApplicationLifecycle { 
    def start(): Unit 
    def stop(): Unit 
} 

abstract class AbstractApplicationDaemon extends Daemon { 
    def application: ApplicationLifecycle 

    def init(daemonContext: DaemonContext) {} 

    def start() = application.start() 

    def stop() = application.stop() 

    def destroy() = application.stop() 
} 

class ApplicationDaemon() extends AbstractApplicationDaemon { 
    def application = new Application 
} 

object ServiceApplication extends App { 

    val application = createApplication() 

    def createApplication() = new ApplicationDaemon 

    private[this] var cleanupAlreadyRun: Boolean = false 

    def cleanup(){ 
    val previouslyRun = cleanupAlreadyRun 
    cleanupAlreadyRun = true 
    if (!previouslyRun) application.stop() 
    } 

    Runtime.getRuntime.addShutdownHook(new Thread(new Runnable { 
    def run() { 
     cleanup() 
    } 
    })) 

    application.start() 
} 


class Application() extends ApplicationLifecycle with Logging { 

    private[this] var started: Boolean = false 

    private val applicationName = "MyApplication" 

    implicit val actorSystem = ActorSystem(s"$applicationName-system") 

    def start() { 
    logger.info(s"Starting $applicationName Service") 

    if (!started) { 
     started = true 

     val myService = actorSystem.actorOf(Props[MyServiceActor], "my-service") 

     IO(Http) ! Http.Bind(myService, interface = "0.0.0.0", port = 8280) 
    } 
    } 

    def stop() { 
    logger.info(s"Stopping $applicationName Service") 

    if (started) { 
     started = false 
     actorSystem.shutdown() 
    } 
    } 

} 

sonra, /etc/mycompany klasöründe sizi bazı dış yapılandırmaları ekleyin /opt/myapplication/myapplication.jar (a şişman kavanoz için kullanılması sbt-montaj) kavanoz dağıtırsanız Jsvc kullanarak örneğin bir /etc/init.d/myapplication komut o sarabilirsiniz:

#!/bin/sh 
### BEGIN INIT INFO 
# Provides:   myapplication 
# Required-Start: $local_fs $remote_fs $network 
# Required-Stop:  $local_fs $remote_fs $network 
# Should-Start:  $named 
# Should-Stop:  $named 
# Default-Start:  2 3 4 5 
# Default-Stop:  0 1 6 
# Short-Description: Control myapplication 
# Description:  Control the myapplication daemon. 
### END INIT INFO 

set -e 

if [ -z "${JAVA_HOME}" ]; then 
     JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:/bin/java::") 
fi 
JAVA_OPTS="-Xms512m -Xmx1024m" 

APP=myapplication 

PID=/var/run/${APP}.pid 
OUT_LOG=/var/log/myapplication/${APP}_out.log 
ERR_LOG=/var/log/myapplication/${APP}_err.log 

DAEMON_USER=yourserviceuser 

APP_LOG_CONFIG=/etc/mycompany/${APP}_logback.xml 
APP_CONFIG=/etc/mycompany/${APP}.conf 
APP_HOME=/opt/${APP} 
APP_CLASSPATH=$APP_HOME/${APP}.jar 
APP_CLASS=com.example.myapplication.server.ApplicationDaemon 

if [ -n "$APP_LOG_CONFIG}" ]; then 
     JAVA_OPTS="-Dlogback.configurationFile=${APP_LOG_CONFIG} ${JAVA_OPTS}" 
fi 

DAEMON_ARGS="-home ${JAVA_HOME} -Dconfig.file=${APP_CONFIG} ${JAVA_OPTS} -pidfile ${PID} -user ${DAEMON_USER} -outfile ${OUT_LOG} -errfile ${ERR_LOG} -cp ${APP_CLASSPATH} ${APP_CLASS}" 

. /lib/lsb/init-functions 

case "$1" in 
     start) 
       log_daemon_msg "Starting ${APP}" 
       cd ${APP_HOME} && jsvc ${DAEMON_ARGS} 
       log_end_msg 0 
       ;; 
     stop) 
       log_daemon_msg "Stopping ${APP}" 
       cd ${APP_HOME} && jsvc -stop ${DAEMON_ARGS} 
       log_end_msg 0 
       ;; 
     *) 
       log_success_msg "Usage: {start|stop}" 
       echo "Usage: {start|stop}" 
       exit 1 
       ;; 
esac 

exit 0 

ile artık can sudo service myapplication start|stop

Ve otomatik Bu cin yaklaşım ben Sprey uygulamalarıyla çalıştığını bu komutu

sudo update-rc.d myapplication defaults 

sonra açılışta başlayacak çalıştırmak istediğiniz belirtildiği gibi eğer.

+0

Mükemmel cevap! Maalesef, "/ etc/mycompany klasörüne bazı harici konfigürasyonlar ekleyemiyorum" bölümünü almıyorum. Kavanozun vb. Hala harika cevap. – Jack

+0

Harici yapılandırmalar isteğe bağlıdır ve APP_LOG_CONFIG ve APP_CONFIG tarafından başvurulan ve bir jarse yapılandırmanızın içinde geçersiz kılabilen bir logonun application.conf yapılandırmasıdır. Ama bu javaoptions'ları da dinlemek için build.sbt ve Build.scala'ya ihtiyacınız var. Onlara ihtiyacınız yoksa, referanslarını kaldırarak DAEMON_ARGS ve JAVA_OPTS'nizi basitleştirebilirsiniz. – flurdy

0

maven uygun aşağıdaki eklenti kullanılabilir ise: kolayca sbt Deri bir kedi çeşitli yolları vardır