Create microservice
Servlet (webApp) microservice
JLupin Next Server supports creating web application with use of servlet containers. For this Spring Boot is used. Application created this way is also a microservice but with exposed full http API.
Simple example is shown below
package com.jlupin.sample.springboot;
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;
@Controller
@EnableAutoConfiguration
public class ExampleController {
private final static Logger logger = LoggerFactory.getLogger(ExampleController.class);
@RequestMapping("/")
@ResponseBody
String home() {
logger.info("called home() method");
return "Hello JLupin";
}
public static void main(String[] args) throws Exception {
SpringApplication.run(ExampleController.class, args);
}
}
Running microservice
When your microservice is done compile it into war file. Then put this file with all other required by your microservice (like servlet_configuration.yml, jlupin logger configuration file, properties file, etc.) into directory which name is your microservice name inside server/application
directory. To start it just run control.sh/.cmd
and type in command microservice start [your_microservice_name]
.
Example microservice configuration file is shown below full configuration file description:
SERVERS:
HTTP:
type: spring_boot
httpPrimaryPort: -1
httpSecondaryPort: -1
waitForFinishExecuteAllRequests: true
waitToShutdownThreadsOnStop: 5000
springBootLoaderClassName: org.springframework.boot.loader.WarLauncher
contextName: /example
TRANSMISSION:
readTimeout: 480000
isWaitForFinishExecuteAllRequests: false
waitToShutdownThreadsOnStop: 60000
backlog: 0
receiveBufferSize: 0
isReuseAddress: false
threadPoolSize: 8
isLogPeriodicOnDebug: true
isDestroyThreadOnTimeout: false
threadExecutingTimeOut: 3600000
PROPERTIES:
#jvmOptions1: '-Xms128M -Xmx256M -agentlib:jdwp=transport=dt_socket,address=12998,server=y,suspend=n'
jvmOptions1: '-Xms64M -Xmx192M' #jvmOptions_2 - default the same as jvmOptions_1
#jvmOptions2: '-Xms128M -Xmx256M'
externalPort: '8000'
version: '1.0'
switchDelayTime: 1000
connectionSocketTimeoutInMillis: 1000
readTimeoutInMillis: 30000
isKeepAlive: false
isOOBInline: false
isTcpNoDelay: false
isReuseAddress: false
sendBufferSize: 0
receiveBufferSize: 0
soLinger: 0
trafficClass: 0
#javaExecutablePath: 'c:\\jvm\\bin\\java.exe'
#additionalClassPath: 'c:\\temp\\*'
isStartOnMainServerInitialize: true
priorityStartOnMainServerInitialize: 4
waitForProcessInitResponseTimeInMillis: 90000
waitForProcessStartResponseTimeInMillis: 90000
waitForProcessDestroyResponseTimeInMillis: 30000
isAllFilesToJVMAppClassLoader: true
isArchiveOnStart: false
startLogMode: INFO
isInitErrorCauseWithNetworkInformation: true
checkAvailableScript: 'function isAvailable(checkResponseTimeInMillis, jrmcActiveThreads, jrmcMaxThreads,
queueActiveThreads, queueMaxThreads, servletActiveThreads, servletMaxThreads,
jvmMaxMemoryInBytes, jvmTotalMemoryInBytes, jvmFreeMemoryInBytes,
jvmProcessCpuLoadInPercentage, userAvailableFlag) {
var isAvailableByUser = Boolean(userAvailableFlag);
if(checkResponseTimeInMillis > 20000 || !isAvailableByUser) {
return false;
}
return true;
}'
INITIALIZING_LOGGER:
#directoryPath: '/logs/server'
#fileName: 'file_name'
fileExtension: 'log'
fileSizeInMB: 20
maxFiles: 10
MEMORY_ERRORS:
isRestartOnError: true
howManyTimes: 4
percentageGrowth: 15
isHeapDump: true
THREAD_POOLS:
THREAD_POOL_1:
size: 8
waitingTimeForTasksCompletionInMillis: 10000
#THREAD_POOL_2:
# size: 8
# waitingTimeForTasksCompletionInMillis: 10000
Servlet (webApp) microservice - more complex example with Maven
JLupin Next Server supports creating web application with use of servlet containers. For this Spring Boot is used. Application created this way is also a microservice but with exposed full http API.
Microservice pom.xml configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<name>example</name>
<groupId>com.jlupin.sample.springboot</groupId>
<artifactId>example-implementation</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<repositories>
<!-- Repository is also accessible using https connection: -->
<!-- https://support.jlupin.com/maven2/ -->
<repository>
<id>jlupin-central</id>
<name>jlupin</name>
<url>http://support.jlupin.com/maven2/</url>
</repository>
</repositories>
<pluginRepositories>
<!-- Repository is also accessible using https connection: -->
<!-- https://support.jlupin.com/maven2/ -->
<pluginRepository>
<id>jlupin-central</id>
<name>jlupin</name>
<url>http://support.jlupin.com/maven2/</url>
</pluginRepository>
</pluginRepositories>
<properties>
<jlupin.server.version>1.4.1.0-RC4</jlupin.server.version>
<jlupin.servlet.monitor.version>1.0.0</jlupin.servlet.monitor.version>
</properties>
<dependencies>
<!-- JLupin dependencies -->
<dependency>
<groupId>com.jlupin</groupId>
<artifactId>jlupin-client-assembly</artifactId>
<version>${jlupin.server.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jlupin</groupId>
<artifactId>jlupin-spring-boot-2-servlet-monitor</artifactId>
<version>${jlupin.servlet.monitor.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.name}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Section with exclusion of spring-boot-starter-logging
is described in chapter Logging.
Spring Boot starter class:
package com.jlupin.sample.springboot;
import com.jlupin.sample.springboot.configuration.ExampleSpringConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootApplicationStarter {
public static void main(String[] args) throws Exception {
SpringApplication.run(ExampleSpringConfiguration.class, args);
}
}
Configuration class:
package com.jlupin.sample.springboot.configuration;
import com.jlupin.impl.client.util.JLupinClientUtil;
import com.jlupin.interfaces.client.delegator.JLupinDelegator;
import com.jlupin.interfaces.common.enums.PortType;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan({
"com.jlupin.sample.springboot",
"com.jlupin.servlet.monitor.configuration"
})
public class ExampleSpringConfiguration {
@Bean
public JLupinDelegator getJLupinDelegator() {
return JLupinClientUtil.generateInnerMicroserviceLoadBalancerDelegator(PortType.JLRMC);
}
}
Part with added package com.jlupin.servlet.monitor.configuration
for component scan is to enable serlvet microservice monitoring for JLupin. For this purpose also depency to jlupin-servlet-monitor
is added in pom.xml
file.
Example controller class:
package com.jlupin.sample.springboot.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ExampleController {
private final static Logger logger = LoggerFactory.getLogger(ExampleController.class);
@RequestMapping("/")
@ResponseBody
String home() {
logger.info("called home() method");
return "Hello JLupin";
}
}
Create servler_configuration.yml
file with microservice configuration full configuration file description:
SERVERS:
HTTP:
type: spring_boot
httpPrimaryPort: -1
httpSecondaryPort: -1
waitForFinishExecuteAllRequests: true
waitToShutdownThreadsOnStop: 5000
springBootLoaderClassName: org.springframework.boot.loader.WarLauncher
contextName: /example
TRANSMISSION:
readTimeout: 480000
isWaitForFinishExecuteAllRequests: false
waitToShutdownThreadsOnStop: 60000
backlog: 0
receiveBufferSize: 0
isReuseAddress: false
threadPoolSize: 8
isLogPeriodicOnDebug: true
isDestroyThreadOnTimeout: false
threadExecutingTimeOut: 3600000
PROPERTIES:
#jvmOptions1: '-Xms128M -Xmx256M -agentlib:jdwp=transport=dt_socket,address=12998,server=y,suspend=n'
jvmOptions1: '-Xms64M -Xmx192M' #jvmOptions_2 - default the same as jvmOptions_1
#jvmOptions2: '-Xms128M -Xmx256M'
externalPort: '8000'
version: '1.0'
switchDelayTime: 1000
connectionSocketTimeoutInMillis: 1000
readTimeoutInMillis: 30000
isKeepAlive: false
isOOBInline: false
isTcpNoDelay: false
isReuseAddress: false
sendBufferSize: 0
receiveBufferSize: 0
soLinger: 0
trafficClass: 0
#javaExecutablePath: 'c:\\jvm\\bin\\java.exe'
#additionalClassPath: 'c:\\temp\\*'
isStartOnMainServerInitialize: true
priorityStartOnMainServerInitialize: 4
waitForProcessInitResponseTimeInMillis: 90000
waitForProcessStartResponseTimeInMillis: 90000
waitForProcessDestroyResponseTimeInMillis: 30000
isAllFilesToJVMAppClassLoader: true
isArchiveOnStart: false
startLogMode: INFO
isInitErrorCauseWithNetworkInformation: true
checkAvailableScript: 'function isAvailable(checkResponseTimeInMillis, jrmcActiveThreads, jrmcMaxThreads,
queueActiveThreads, queueMaxThreads, servletActiveThreads, servletMaxThreads,
jvmMaxMemoryInBytes, jvmTotalMemoryInBytes, jvmFreeMemoryInBytes,
jvmProcessCpuLoadInPercentage, userAvailableFlag) {
var isAvailableByUser = Boolean(userAvailableFlag);
if(checkResponseTimeInMillis > 20000 || !isAvailableByUser) {
return false;
}
return true;
}'
INITIALIZING_LOGGER:
#directoryPath: '/logs/server'
#fileName: 'file_name'
fileExtension: 'log'
fileSizeInMB: 20
maxFiles: 10
MEMORY_ERRORS:
isRestartOnError: true
howManyTimes: 4
percentageGrowth: 15
isHeapDump: true
THREAD_POOLS:
THREAD_POOL_1:
size: 8
waitingTimeForTasksCompletionInMillis: 10000
#THREAD_POOL_2:
# size: 8
# waitingTimeForTasksCompletionInMillis: 10000
It is important to configure context path for microservice (see paramter SERVERS -> HTTP -> contextName above) and not to set it inside application or with properties file. JLupin will take care of it and will know context path this way.
Log configuration file should be placed in resource directory and also in microservice directory (described here):
<?xml version="1.0" encoding="UTF-8"?>
<!-- ===================================================================== -->
<!-- -->
<!-- Log4j2 Configuration -->
<!-- -->
<!-- ===================================================================== -->
<!--
| For more configuration information and examples see the Apache Log4j2
| website: https://logging.apache.org/log4j/2.x/index.html
-->
<Configuration status="WARN">
<!-- Extract log directory and file name into variables -->
<Properties>
<Property name="logDirectory">../logs/microservice/example</Property>
<Property name="logFileName">microservice</Property>
</Properties>
<Appenders>
<!-- RollingFileAppender configured to role every day -->
<RollingFile name="FILE">
<FileName>${logDirectory}/${logFileName}.log</FileName>
<FilePattern>${logDirectory}/${logFileName}.%d{yyyy-MM-dd}.log</FilePattern>
<!-- Compress log files to gzip -->
<!-- More configuration https://logging.apache.org/log4j/2.x/manual/appenders.html#DefaultRolloverStrategy -->
<!-- <FilePattern>/.%d{yyyy-MM-dd}.log.gz</FilePattern> -->
<!-- Do not truncate file -->
<Append>true</Append>
<!-- The default pattern: Date Priority [Category] (Thread) Message\n -->
<PatternLayout pattern="%d %-5p [%c] (%t) %m%n"/>
<Policies>
<!-- Rollover every microservice start - very useful for debugging -->
<!-- <OnStartupTriggeringPolicy /> -->
<!-- Rollover at the top of each day -->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<!-- Rollover if file size is greater than 200 MB -->
<!-- <SizeBasedTriggeringPolicy size="200 MB"/> -->
</Policies>
<!-- Keep last 10 log files -->
<!-- More configuration https://logging.apache.org/log4j/2.x/manual/appenders.html#DefaultRolloverStrategy -->
<!-- <DefaultRolloverStrategy max="10" /> -->
</RollingFile>
<!-- AsyncAppender for high performance -->
<Async name="ASYNC_FILE">
<BufferSize>1000</BufferSize>
<AppenderRef ref="FILE"/>
</Async>
</Appenders>
<Loggers>
<!-- Setup for root logger with AsyncAppender -->
<Root level="info">
<AppenderRef ref="ASYNC_FILE"/>
</Root>
</Loggers>
</Configuration>
If you want you can also put application.properties
file in your microservice folder and JLupin will provide these setting for Spring BOOT application.
Running microservice
When your microservice is done compile it into war file. Then put this file with all other required by your microservice (like servlet_configuration.yml, jlupin logger configuration file, properties file, etc.) into directory which name is your microservice name inside server/application
directory. To start it just run control.sh/.cmd
and type in command microservice start [your_microservice_name]
.