Esta página ainda não está disponível no idioma selecionado. Estamos trabalhando para adicionar mais opções de idiomas. Agradecemos sua compreensão.

Compute
Elastic Cloud Server
Huawei Cloud Flexus
Bare Metal Server
Auto Scaling
Image Management Service
Dedicated Host
FunctionGraph
Cloud Phone Host
Huawei Cloud EulerOS
Networking
Virtual Private Cloud
Elastic IP
Elastic Load Balance
NAT Gateway
Direct Connect
Virtual Private Network
VPC Endpoint
Cloud Connect
Enterprise Router
Enterprise Switch
Global Accelerator
Management & Governance
Cloud Eye
Identity and Access Management
Cloud Trace Service
Resource Formation Service
Tag Management Service
Log Tank Service
Config
OneAccess
Resource Access Manager
Simple Message Notification
Application Performance Management
Application Operations Management
Organizations
Optimization Advisor
IAM Identity Center
Cloud Operations Center
Resource Governance Center
Migration
Server Migration Service
Object Storage Migration Service
Cloud Data Migration
Migration Center
Cloud Ecosystem
KooGallery
Partner Center
User Support
My Account
Billing Center
Cost Center
Resource Center
Enterprise Management
Service Tickets
HUAWEI CLOUD (International) FAQs
ICP Filing
Support Plans
My Credentials
Customer Operation Capabilities
Partner Support Plans
Professional Services
Analytics
MapReduce Service
Data Lake Insight
CloudTable Service
Cloud Search Service
Data Lake Visualization
Data Ingestion Service
GaussDB(DWS)
DataArts Studio
Data Lake Factory
DataArts Lake Formation
IoT
IoT Device Access
Others
Product Pricing Details
System Permissions
Console Quick Start
Common FAQs
Instructions for Associating with a HUAWEI CLOUD Partner
Message Center
Security & Compliance
Security Technologies and Applications
Web Application Firewall
Host Security Service
Cloud Firewall
SecMaster
Anti-DDoS Service
Data Encryption Workshop
Database Security Service
Cloud Bastion Host
Data Security Center
Cloud Certificate Manager
Edge Security
Blockchain
Blockchain Service
Web3 Node Engine Service
Media Services
Media Processing Center
Video On Demand
Live
SparkRTC
MetaStudio
Storage
Object Storage Service
Elastic Volume Service
Cloud Backup and Recovery
Storage Disaster Recovery Service
Scalable File Service Turbo
Scalable File Service
Volume Backup Service
Cloud Server Backup Service
Data Express Service
Dedicated Distributed Storage Service
Containers
Cloud Container Engine
SoftWare Repository for Container
Application Service Mesh
Ubiquitous Cloud Native Service
Cloud Container Instance
Databases
Relational Database Service
Document Database Service
Data Admin Service
Data Replication Service
GeminiDB
GaussDB
Distributed Database Middleware
Database and Application Migration UGO
TaurusDB
Middleware
Distributed Cache Service
API Gateway
Distributed Message Service for Kafka
Distributed Message Service for RabbitMQ
Distributed Message Service for RocketMQ
Cloud Service Engine
Multi-Site High Availability Service
EventGrid
Dedicated Cloud
Dedicated Computing Cluster
Business Applications
Workspace
ROMA Connect
Message & SMS
Domain Name Service
Edge Data Center Management
Meeting
AI
Face Recognition Service
Graph Engine Service
Content Moderation
Image Recognition
Optical Character Recognition
ModelArts
ImageSearch
Conversational Bot Service
Speech Interaction Service
Huawei HiLens
Video Intelligent Analysis Service
Developer Tools
SDK Developer Guide
API Request Signing Guide
Terraform
Koo Command Line Interface
Content Delivery & Edge Computing
Content Delivery Network
Intelligent EdgeFabric
CloudPond
Intelligent EdgeCloud
Solutions
SAP Cloud
High Performance Computing
Developer Services
ServiceStage
CodeArts
CodeArts PerfTest
CodeArts Req
CodeArts Pipeline
CodeArts Build
CodeArts Deploy
CodeArts Artifact
CodeArts TestPlan
CodeArts Check
CodeArts Repo
Cloud Application Engine
MacroVerse aPaaS
KooMessage
KooPhone
KooDrive
Help Center/ ServiceStage/ FAQs/ Application Development/ How Do I Package a Java or Tomcat Application?

How Do I Package a Java or Tomcat Application?

Updated on 2024-12-16 GMT+08:00

ServiceStage allows you to compress a Java or Tomcat application into a .zip or .tar.gz package for deploying a component on a VM.

Application Package Directory Structure

The following uses the Java application package demoJavaExample.zip to illustrate the application package directory structure:

demoJavaExample/
│
├── scripts/
│   │      ├── pre-stop.sh
│   │      ├── stop.sh
│   │      ├── uninstall.sh
│   │      ├── install.sh
│   │      ├── start.sh
│   │      ├── check.sh
│   │      ├── post-start.sh
├── packages/
│   │      ├── weather-1.0.0.jar
├── config/
│   │      ├── system.cfg
├── appspec.yml
NOTE:

The prefix of the package name must be the same as the directory name of the decompressed file. For example, a package named demoJavaExample.zip will have a directory after decompression named demoJavaExample.

The directories and files in the application package are described as follows:

  • scripts: (mandatory) stores script files executed in each application lifecycle.
  • packages: (mandatory) stores application JAR or WAR packages.
  • config: (mandatory) stores application configuration information. For Java applications, the system.cfg file is stored. For Tomcat applications, the system.cfg, logging.properties, and server.xml files are stored.
  • appspec.yml: (mandatory) records the lifecycle definition and also specifies information such as health check.

appspec.yml File Description

As shown in the following, the appspec.yml file defines the entire deployment process, and the environment variables and health check information used during deployment.

spec:
  # Custom user for application running.
  deps:
    - name: "@os/linux/user@1.0"
      user: www
      group: www
      home: /home/www

  # Directly import the environment variables of the application lifecycle script.
  env:
  - name: APP_ENV
    value: "{{app.env}}"

  # Import the environment variables of the application lifecycle script
in the /opt/application/${appName}/${appVersion}/${instanceId}/servicestage-vmapp/application.conf file
as a file.
  value:
  - name: APP_VALUE
    value: "{{app.value}}"

  # Application health check.
  probes:
    # Interface health check.
    # health:
    #   exec:
    #     method: GET
    #     request: http://127.0.0.1:8080/healthcheck
    #     timeout: 5

    # Script command health check.
    liveness:
      exec:
        command:
          - ps -ef | grep ${APP_HOME}/apache-tomcat-*/bin/bootstrap.jar | grep -v grep   # Currently, only APP_HOME can be used to obtain environment variables.
        timeout: 300
        runas: www

  # Application lifecycle script.
  lifecycle:
    install:
      - command: scripts/install.sh
        timeout: 300
    check:
      - command: scripts/check.sh
        timeout: 300
        runas: www
    start:
      - command: scripts/start.sh
        timeout: 300
        runas: www
    post-start:
      - command: scripts/post-start.sh
        timeout: 300
        runas: www
    pre-stop:
      - command: scripts/pre-stop.sh
        timeout: 300
        runas: www
    stop:
      - command: scripts/stop.sh
        timeout: 300
        runas: www
    uninstall:
      - command: scripts/uninstall.sh
        timeout: 300
  • deps: defines the custom user for application running. Set this field by referring to the following example.
    deps:
        - name: "@os/linux/user@1.0"
          user: www
          group: www
          home: /home/www
  • env: records the environment variables during the running of each script. The environment variables can be directly imported during script running.
  • value: saved in the ${APP_HOME}/servicestage-vmapp/application.conf file. To use these values in the script, run the following command at the beginning of the script:
    #!/bin/bash 
      . ${APP_HOME}/servicestage-vmapp/application.conf
    # dosomething
  • probes: records either health check command or interface, or both.
  • health: accesses the health check interface to check the component status.
    • method: HTTP method used to access the interface.
    • request: access address.
    • body: request body.
    • timeout: timeout interval, in seconds.
  • liveness: runs a command to check the component status.
    • command: command used to check the status.
    • runas: Linux user who runs the command. You are advised to set this parameter to www or leave it empty.
    • timeout: timeout interval, in seconds.
  • lifecycle: script or command executed in each lifecycle.
    • command: script file to be executed. The value must be a file path relative to the ${APP_HOME} directory.
    • timeout: timeout interval, in seconds.
    • runas: user who executes the command. Must be www or left empty.

Lifecycle execution sequence:

  • Deployment sequence: ServiceStage installation technology stack + install.sh -> start.sh -> check.sh -> post-start.sh
  • Upgrade/Rollback sequence: ServiceStage installation technology stack + install.sh -> pre-stop.sh -> stop.sh -> uninstall.sh + ServiceStage uninstallation technology stack -> start.sh -> check.sh ->post-start.sh
  • Deletion sequence: pre-stop.sh -> stop.sh -> uninstall.sh + ServiceStage

config Description

  • system.cfg file
    1. Set the config parameter.

      When creating a component based on a VM, you can set some configuration items by referring to Adding a Configuration Item. ServiceStage stores the configured configuration items in the ${APP_HOME}/config/system.cfg file as key-value pairs. You can also preset some configuration parameters in the config file. Example:

      # Format of the content stored in the system.cfg file
      key1=value1
      key2=value2
    2. Reference the config parameter.

      Example:

      #!/bin/bash 
        . ${APP_HOME}/config/system.cfg 
        . ${APP_HOME}/config/user_config.cfg 
        echo ${key1}
  • server.xml file

    See server.xml Description of Tomcat.

  • logging.properties file

    See logging.properties Description of Tomcat.

packages Directory Description

This folder holds the JAR and WAR packages to be executed when running commands in the script.

scripts Directory Description

This folder stores the scripts executed in each lifecycle of an application.

Default System Configurations

The default configurations are stored in the ${APP_HOME}/servicestage-vmapp/application.conf file. The file content is:

export LOG_PATH=/var/log/application/zqb-4-vm-wqd-2-7f6fbc/3c719644-f9f5-46b4-a06a-61fcf163e5b5
export APP_HOME=/opt/application/zqb-4-vm-wqd-2-7f6fbc/2023.1207.11314/3c719644-f9f5-46b4-a06a-61fcf163e5b5
export TOMCAT_STACK_HOME=/opt/application/zqb-4-vm-wqd-2-7f6fbc/2023.1207.11314/3c719644-f9f5-46b4-a06a-61fcf163e5b5/apache-tomcat-8.5.82
export JRE_STACK_HOME=/opt/application/zqb-4-vm-wqd-2-7f6fbc/2023.1207.11314/3c719644-f9f5-46b4-a06a-61fcf163e5b5/jre1.8
export APP_VALUE="{{app.value}}"
export APP_USER=www
export APP_GROUP=www
  • LOG_PATH: log recording path. Application logs are recorded in the log file in LOG_PATH and named {lifecycle}_app.log.
  • APP_HOME: records the running environment of the current application.
  • TOMCAT_STACK_HOME: home directory of Tomcat.
  • JRE_STACK_HOME: home directory of JRE.
  • APP_VALUE: environment variable specified in appspec.yml.
  • APP_USER: the file's user.
  • APP_GROUP: the file's owner group.
NOTE:

Default system configurations are not directly displayed in environment variables. The available script environment variables are: APP_HOME, those specified in appspec.yml, and those specified in Adding a Component Environment Variable.

Script Writing Description

The directory structure for executing scripts on ServiceStage is:

APP_HOME/
│
├── scripts/
│   │      ├── pre-stop.sh
│   │      ├── stop.sh
│   │      ├── uninstall.sh
│   │      ├── install.sh
│   │      ├── start.sh
│   │      ├── check.sh
│   │      ├── post-start.sh
│   ├──packages/
│   │      ├── my-app.jar/my-app.war
├── config/
│   │      ├── system.cfg
├── servicestage-vmapp/
│   │      ├── application.conf
├── jre1.8
├── apache-tomcat-8.5.82
  • When writing scripts, go to the ${APP_HOME} directory to obtain the locations of other files.
  • To obtain the location of JRE or Tomcat, run the following commands at the beginning of the script. Use ${APP_HOME}/servicestage-vmapp/application.conf to load environment variables and then use ${JRE_STACK_HOME} or ${TOMCAT_STACK_HOME} to obtain the values.
  • ServiceStage reports logs in the ${LOG_PATH} directory. Therefore, record them in the log file in the ${LOG_PATH} directory and name them {lifecycle}_app.log to facilitate subsequent log reporting.
  • It is recommended that the script start with the following lines to obtain environment variables and user configurations, and specify the technology stack home directory, log output path, and current execution address.
    #!/bin/bash
    
    # Obtain user configurations and specify environment variables.
    . ${APP_HOME}/config/system.cfg
    . ${APP_HOME}/servicestage-vmapp/application.conf
    
    # Specify the technology stack home directory.
    JRE_HOME=${JRE_STACK_HOME}
    TOMCAT_HOME=${TOMCAT_STACK_HOME}
    
    # Specify the log output path.
    installLog="${LOG_PATH}/install_app.log"
    
    # Method of printing logs.
    function writeLog()
    {
        msg="$1\n"
        printf "[`date '+%Y-%m-%d %H:%M:%S'`] $msg" | sudo tee -a ${installLog};
    }
    
    writeLog "-----begin!------"

server.xml Description of Tomcat

  • When creating the Tomcat component, you can prepare the server.xml file in advance and copy the file to the Tomcat directory. (You are advised to perform this step in the install lifecycle.)
    #!/bin/bash
    . ${APP_HOME}/servicestage-vmapp/application.conf 
    cp ${APP_HOME}/conf/server.xml ${TOMCAT_STACK_HOME}/conf/server.xml
  • ServiceStage presets a server.xml file in ${TOMCAT_STACK_HOME}/conf/server.xml. The file contains four placeholders. You need to replace them by referring to the following code:
    #!/bin/bash
    . ${APP_HOME}/servicestage-vmapp/application.conf
    function replacePara()
    {
        sWord=$1
        dWord=$2
        theFile=$3
        if [[ "$sWord" == "" || "$theFile" == "" ]]
        then
            writeLog "[ERROR] ReplacePara has empty param, \$1:$sWord, \$3:$theFile"
            return 1
        fi
    
        if [[ ! -f ${theFile} ]]
        then
            writeLog "[ERROR] File $theFile does not exist."
            return 1
        fi
        count=`grep -c "$sWord" ${theFile}`
        if [[ "${count}" == "0" ]];then
            return 0
        fi
        sed "s#$sWord#${dWord}#g" ${theFile} > ${theFile}.temp
        if [[ "$?" != "0" ]]
        then
            writeLog "[ERROR] Sed command in replacePara error."
            return 1
        fi
        mv -f ${theFile}.temp ${theFile}
    }
    replacePara "@{LOG_FILE_PATH_APP}" "${LOG_FILE_PATH_APP}" ${TOMCAT_HOME}/conf/server.xml
    replacePara "@{http_port}" "${instance_port_port}" ${TOMCAT_HOME}/conf/server.xml
    replacePara "@{server_port}" "${server_port}" ${TOMCAT_HOME}/conf/server.xml
    replacePara "@{APP_PACKAGE_NAME}" "examples.war" ${TOMCAT_HOME}/conf/server.xml
    • @{server_port}: port number of the Tomcat server.
    • @{APP_PACKAGE_NAME}: path of the WAR package relative to ${TOMCAT_STACK_HOME}.
    • @{http_port}: port number of the Tomcat connector.
    • @{LOG_FILE_PATH_APP}: path for printing Tomcat logs.

logging.properties Description of Tomcat

Prepare the logging.properties file and copy it to the Tomcat directory. Example of copying the code:

#!/bin/bash
. ${APP_HOME}/servicestage-vmapp/application.conf 
cp ${APP_HOME}/conf/logging.properties ${TOMCAT_STACK_HOME}/conf/logging.properties

The logging.properties file contains the following information, where @{LOG_FILE_PATH_APP} is the actual log directory.

handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2localhost.org.apache.juli.AsyncFileHandler, 3manager.org.apache.juli.AsyncFileHandler, 4host-manager.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler

.handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler

1catalina.org.apache.juli.AsyncFileHandler.level = FINE
1catalina.org.apache.juli.AsyncFileHandler.directory = @{LOG_FILE_PATH_APP}
1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina.

2localhost.org.apache.juli.AsyncFileHandler.level = FINE
2localhost.org.apache.juli.AsyncFileHandler.directory = @{LOG_FILE_PATH_APP}
2localhost.org.apache.juli.AsyncFileHandler.prefix = localhost.

3manager.org.apache.juli.AsyncFileHandler.level = FINE
3manager.org.apache.juli.AsyncFileHandler.directory = @{LOG_FILE_PATH_APP}
3manager.org.apache.juli.AsyncFileHandler.prefix = manager.

4host-manager.org.apache.juli.AsyncFileHandler.level = FINE
4host-manager.org.apache.juli.AsyncFileHandler.directory = @{LOG_FILE_PATH_APP}
4host-manager.org.apache.juli.AsyncFileHandler.prefix = host-manager.

java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.AsyncFileHandler

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.AsyncFileHandler

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.AsyncFileHandler

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.AsyncFileHandler

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.AsyncFileHandler

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.AsyncFileHandler

FAQ

  • How do I run a script as user root?
    1. Write the content to be executed by user root into the root-install.sh script.
    2. Run the following statement in the install.sh script to be executed. ${ROOT_PASSWORD} is the password of user root, and the content in the double quotation marks after -c is the command to be executed. Environment variables will be lost after you switch user, so add the required environment variables before sh.
      echo "${ROOT_PASSWORD}" | su - root -c "APP_HOME=${APP_HOME} sh root-install.sh"
    3. If you get the error message "su: Permission denied", find the /etc/pam.d/su file and comment out "auth required pam_wheel.so use_uid."

Usamos cookies para aprimorar nosso site e sua experiência. Ao continuar a navegar em nosso site, você aceita nossa política de cookies. Saiba mais

Feedback

Feedback

Feedback

0/500

Selected Content

Submit selected content with the feedback