This is an automated email from the ASF dual-hosted git repository. jongyoul pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push: new ee2b527 [ZEPPELIN-3422] Add JMX Support (#3272) ee2b527 is described below commit ee2b52768a6c2defb31d44783c347f0e2de65ddb Author: Jongyoul Lee <jongy...@gmail.com> AuthorDate: Sat Dec 29 12:26:35 2018 +0900 [ZEPPELIN-3422] Add JMX Support (#3272) * Revise jmx features with Jetty's way --- bin/common.cmd | 8 --- bin/common.sh | 12 ----- conf/zeppelin-env.cmd.template | 2 +- conf/zeppelin-env.sh.template | 2 +- zeppelin-server/pom.xml | 7 +++ .../org/apache/zeppelin/server/ZeppelinServer.java | 58 ++++++++++++++++++++-- .../org/apache/zeppelin/socket/NotebookServer.java | 11 ++-- .../zeppelin/socket/NotebookServerMBean.java | 26 ---------- .../interpreter/InterpreterSettingManager.java | 9 ++-- .../InterpreterSettingManagerMBean.java | 24 --------- 10 files changed, 74 insertions(+), 85 deletions(-) diff --git a/bin/common.cmd b/bin/common.cmd index 21657c1..13f33e5 100644 --- a/bin/common.cmd +++ b/bin/common.cmd @@ -71,14 +71,6 @@ if not defined ZEPPELIN_JAVA_OPTS ( set ZEPPELIN_JAVA_OPTS=%ZEPPELIN_JAVA_OPTS% -Dfile.encoding=%ZEPPELIN_ENCODING% %ZEPPELIN_MEM% ) -if defined ZEPPELIN_JMX_ENABLE ( - if not defined ZEPPELIN_JMX_PORT ( - set ZEPPELIN_JMX_PORT="9996" - } - set JMX_JAVA_OPTS=" -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=${ZEPPELIN_JMX_PORT} -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" - set ZEPPELIN_JAVA_OPTS=%JMX_JAVA_OPTS% %ZEPPELIN_JAVA_OPTS -) - if not defined JAVA_OPTS ( set JAVA_OPTS=%ZEPPELIN_JAVA_OPTS% ) else ( diff --git a/bin/common.sh b/bin/common.sh index c56fbd4..6447ec8 100644 --- a/bin/common.sh +++ b/bin/common.sh @@ -121,18 +121,6 @@ JAVA_OPTS+=" ${ZEPPELIN_JAVA_OPTS} -Dfile.encoding=${ZEPPELIN_ENCODING} ${ZEPPEL JAVA_OPTS+=" -Dlog4j.configuration=file://${ZEPPELIN_CONF_DIR}/log4j.properties" export JAVA_OPTS -if [[ x"${ZEPPELIN_JMX_ENABLE}" == x"true" ]]; then - if [[ -z "${ZEPPELIN_JMX_PORT}" ]]; then - ZEPPELIN_JMX_PORT="9996" - fi - JMX_JAVA_OPTS+=" -Dcom.sun.management.jmxremote" - JMX_JAVA_OPTS+=" -Dcom.sun.management.jmxremote.port=${ZEPPELIN_JMX_PORT}" - JMX_JAVA_OPTS+=" -Dcom.sun.management.jmxremote.authenticate=false" - JMX_JAVA_OPTS+=" -Dcom.sun.management.jmxremote.ssl=false" - JAVA_OPTS="${JMX_JAVA_OPTS} ${JAVA_OPTS}" -fi -export JAVA_OPTS - JAVA_INTP_OPTS="${ZEPPELIN_INTP_JAVA_OPTS} -Dfile.encoding=${ZEPPELIN_ENCODING}" if [[ -z "${ZEPPELIN_SPARK_YARN_CLUSTER}" ]]; then JAVA_INTP_OPTS+=" -Dlog4j.configuration=file://${ZEPPELIN_CONF_DIR}/log4j.properties" diff --git a/conf/zeppelin-env.cmd.template b/conf/zeppelin-env.cmd.template index e69f23b..83b5ee7 100644 --- a/conf/zeppelin-env.cmd.template +++ b/conf/zeppelin-env.cmd.template @@ -23,7 +23,7 @@ REM set ZEPPELIN_MEM REM Zeppelin jvm mem options Default -Xms1024m REM set ZEPPELIN_INTP_MEM REM zeppelin interpreter process jvm mem options. Default -Xmx1024m -Xms1024m -XX:MaxPermSize=512m REM set ZEPPELIN_INTP_JAVA_OPTS REM zeppelin interpreter process jvm options. REM set ZEPPELIN_JMX_ENABLE REM Enable JMX feature by defining it like "true" -REM set ZEPPELIN_JMX_PORT REM Port number which JMX uses. Default: "9996" +REM set ZEPPELIN_JMX_PORT REM Port number which JMX uses. If not set, JMX won't be enabled REM set ZEPPELIN_LOG_DIR REM Where log files are stored. PWD by default. REM set ZEPPELIN_PID_DIR REM The pid files are stored. /tmp by default. diff --git a/conf/zeppelin-env.sh.template b/conf/zeppelin-env.sh.template index 5aab0e0..74941b9 100644 --- a/conf/zeppelin-env.sh.template +++ b/conf/zeppelin-env.sh.template @@ -24,7 +24,7 @@ # export ZEPPELIN_INTP_JAVA_OPTS # zeppelin interpreter process jvm options. # export ZEPPELIN_SSL_PORT # ssl port (used when ssl environment variable is set to true) # export ZEPPELIN_JMX_ENABLE # Enable JMX feature by defining "true" -# export ZEPPELIN_JMX_PORT # Port number which JMX uses. Default: "9996" +# export ZEPPELIN_JMX_PORT # Port number which JMX uses. If not set, JMX won't be enabled # export ZEPPELIN_LOG_DIR # Where log files are stored. PWD by default. # export ZEPPELIN_PID_DIR # The pid files are stored. ${ZEPPELIN_HOME}/run by default. diff --git a/zeppelin-server/pom.xml b/zeppelin-server/pom.xml index b8da356..75f0af6 100644 --- a/zeppelin-server/pom.xml +++ b/zeppelin-server/pom.xml @@ -227,6 +227,13 @@ <artifactId>jetty-webapp</artifactId> <version>${jetty.version}</version> </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-jmx</artifactId> + <version>${jetty.version}</version> + </dependency> + <dependency> <groupId>org.eclipse.jetty.websocket</groupId> <artifactId>websocket-server</artifactId> diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java index c7f13a6..f924fbd 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java @@ -18,9 +18,13 @@ package org.apache.zeppelin.server; import java.io.File; import java.io.IOException; +import java.lang.management.ManagementFactory; import java.util.EnumSet; +import java.util.Objects; +import java.util.stream.Stream; import javax.inject.Inject; import javax.inject.Singleton; +import javax.management.remote.JMXServiceURL; import javax.servlet.DispatcherType; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @@ -57,6 +61,8 @@ import org.apache.zeppelin.service.ShiroSecurityService; import org.apache.zeppelin.socket.NotebookServer; import org.apache.zeppelin.user.Credentials; import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.jmx.ConnectorServer; +import org.eclipse.jetty.jmx.MBeanContainer; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.SecureRequestCustomizer; @@ -177,6 +183,51 @@ public class ZeppelinServer extends ResourceConfig { // Notebook server setupNotebookServer(webApp, conf, sharedServiceLocator); + // JMX Enable + Stream.of("ZEPPELIN_JMX_ENABLE") + .map(System::getenv) + .map(Boolean::parseBoolean) + .filter(Boolean::booleanValue) + .map(jmxEnabled -> "ZEPPELIN_JMX_PORT") + .map(System::getenv) + .map( + portString -> { + try { + return Integer.parseInt(portString); + } catch (Exception e) { + return null; + } + }) + .filter(Objects::nonNull) + .forEach( + port -> { + try { + MBeanContainer mbeanContainer = + new MBeanContainer(ManagementFactory.getPlatformMBeanServer()); + jettyWebServer.addEventListener(mbeanContainer); + jettyWebServer.addBean(mbeanContainer); + + JMXServiceURL jmxURL = + new JMXServiceURL( + String.format( + "service:jmx:rmi://0.0.0.0:%d/jndi/rmi://0.0.0.0:%d/jmxrmi", + port, port)); + ConnectorServer jmxServer = + new ConnectorServer(jmxURL, "org.eclipse.jetty.jmx:name=rmiconnectorserver"); + jettyWebServer.addBean(jmxServer); + + // Add JMX Beans + // TODO(jl): Need to investigate more about injection and jmx + jettyWebServer.addBean( + sharedServiceLocator.getService(InterpreterSettingManager.class)); + jettyWebServer.addBean(sharedServiceLocator.getService(NotebookServer.class)); + + LOG.info("JMX Enabled with port: {}", port); + } catch (Exception e) { + LOG.warn("Error while setting JMX", e); + } + }); + LOG.info("Starting zeppelin server"); try { jettyWebServer.start(); // Instantiates ZeppelinServer @@ -197,10 +248,7 @@ public class ZeppelinServer extends ResourceConfig { try { jettyWebServer.stop(); if (!conf.isRecoveryEnabled()) { - sharedServiceLocator - .getService(Notebook.class) - .getInterpreterSettingManager() - .close(); + sharedServiceLocator.getService(InterpreterSettingManager.class).close(); } sharedServiceLocator.getService(Notebook.class).close(); Thread.sleep(3000); @@ -223,7 +271,7 @@ public class ZeppelinServer extends ResourceConfig { jettyWebServer.join(); if (!conf.isRecoveryEnabled()) { - sharedServiceLocator.getService(Notebook.class).getInterpreterSettingManager().close(); + sharedServiceLocator.getService(InterpreterSettingManager.class).close(); } } diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java index 40c7461..e83f26f 100644 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java +++ b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java @@ -80,6 +80,9 @@ import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.utils.CorsUtils; import org.apache.zeppelin.utils.InterpreterBindingUtils; import org.apache.zeppelin.utils.TestUtils; +import org.eclipse.jetty.util.annotation.ManagedAttribute; +import org.eclipse.jetty.util.annotation.ManagedObject; +import org.eclipse.jetty.util.annotation.ManagedOperation; import org.eclipse.jetty.websocket.servlet.WebSocketServlet; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; import org.glassfish.hk2.api.ServiceLocator; @@ -90,14 +93,14 @@ import org.slf4j.LoggerFactory; * Zeppelin websocket service. This class used setter injection because all servlet should have * no-parameter constructor */ +@ManagedObject public class NotebookServer extends WebSocketServlet implements NotebookSocketListener, AngularObjectRegistryListener, RemoteInterpreterProcessListener, ApplicationEventListener, ParagraphJobListener, - NoteEventListener, - NotebookServerMBean { + NoteEventListener { /** * Job manager service type. @@ -1843,12 +1846,12 @@ public class NotebookServer extends WebSocketServlet }); } - @Override + @ManagedAttribute public Set<String> getConnectedUsers() { return connectionManager.getConnectedUsers(); } - @Override + @ManagedOperation public void sendMessage(String message) { Message m = new Message(OP.NOTICE); m.data.put("notice", message); diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServerMBean.java b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServerMBean.java deleted file mode 100644 index f94af89..0000000 --- a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServerMBean.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.zeppelin.socket; - -import java.util.Set; - -public interface NotebookServerMBean { - Set<String> getConnectedUsers(); - - void sendMessage(String message); -} diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java index d4468ff..708fcb7 100644 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java +++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java @@ -54,6 +54,8 @@ import org.apache.zeppelin.scheduler.Job; import org.apache.zeppelin.user.AuthenticationInfo; import org.apache.zeppelin.util.ReflectionUtils; import org.apache.zeppelin.storage.ConfigStorage; +import org.eclipse.jetty.util.annotation.ManagedAttribute; +import org.eclipse.jetty.util.annotation.ManagedObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonatype.aether.repository.Proxy; @@ -77,7 +79,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -88,8 +89,8 @@ import java.util.stream.Collectors; * (load/create/update/remove/get) * TODO(zjffdu) We could move it into another separated component. */ -public class InterpreterSettingManager implements InterpreterSettingManagerMBean, - NoteEventListener { +@ManagedObject("interpreterSettingManager") +public class InterpreterSettingManager implements NoteEventListener { private static final Logger LOGGER = LoggerFactory.getLogger(InterpreterSettingManager.class); private static final Map<String, Object> DEFAULT_EDITOR = ImmutableMap.of( @@ -870,7 +871,7 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean } } - @Override + @ManagedAttribute public Set<String> getRunningInterpreters() { Set<String> runningInterpreters = Sets.newHashSet(); for (Map.Entry<String, InterpreterSetting> entry : interpreterSettings.entrySet()) { diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerMBean.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerMBean.java deleted file mode 100644 index 3cc3b08..0000000 --- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerMBean.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.zeppelin.interpreter; - -import java.util.Set; - -public interface InterpreterSettingManagerMBean { - Set<String> getRunningInterpreters(); -}