SpringBoot e-Commerce project mall (35K + STAR) address: github.com/macrozheng/…

Abstract

Online projects can’t be debugged, and offline projects can’t be reproduced. Why can’t we just log and re-publish? With this artifact, both online debugging, and can achieve hot repair, recommended to everyone!

Arthas profile

Arthas is an open source Java diagnostic tool for Alibaba that developers love. It adopts the command line interaction mode and provides rich Tab auto-completion functions to further facilitate problem location and diagnosis.

The installation

To restore a real-world online environment, Arthas will be used to diagnose Java programs in Docker containers.

  • Use arthas – the boot, download the corresponding jar package, download address: alibaba. Making. IO/arthas/arth…

  • Start our Spring Boot application with mall-Tiny-arthas as a Docker container, package and run the script in the project’s SRC \main\ Docker directory;

  • Copy arthas-boot.jar to our application container \ directory;

docker container cp arthas-boot.jar mall-tiny-arthas:/
Copy the code
  • Enter the container and startarthas-boot, can be directly started as a JAR package;
docker exec -it mall-tiny-arthas /bin/bash
java -jar arthas-boot.jar
Copy the code
  • After successful startup, select the serial number of the Java program that you currently want to diagnose, here is1, can begin the diagnosis;

  • The required files will be downloaded and the console will print the following message and Arthas will be installed and started.

Common commands

We are going to start with some of the common Arthas commands and we are going to show you how to use Arthas in a practical way.

dashboard

Using the Dashboard command, you can display a real-time data panel of the current system, including thread information, JVM memory information, and JVM runtime parameters.

thread

View the current thread information, view the thread stack, you can find out the current most CPU thread.

Common commands:

Print stack information for the current three busiest threads
thread -n 3
# check the stack information for all threads with ID 1
thread 1
Find the thread that is currently blocking another thread
thread -b
# view the thread in the specified state
thread -state WAITING
Copy the code

sysprop

View the system attributes of the current JVM. For example, if the container time zone is different from that of the host, run the following command to view the time zone information.

sysprop |grep timezone
Copy the code
user.timezone                  Asia/Shanghai
Copy the code

sysenv

Take a look at the environment properties of the JVM, such as the Spring Boot configuration for which environment we are currently enabling.

logger

The logger command is useful for viewing log information and changing the log level.

For example, in the production environment, logs at the DEBUG level are not generated. You can enable logs at the DEBUG level temporarily when you troubleshoot faults online. This section describes how to do so.

  • Our app uses this by defaultINFOLog levelloggerCommand to view;

  • Run the following command to change the log level toDEBUG, need to use-cParameter specifies the HASH value of the classloader;
logger -c 21b8d17c --name ROOT --level debug
Copy the code
  • To useloggerThe command is displayedROOTLevel logs have changed;

  • usedocker logs -f mall-tiny-arthasRun the DEBUG command to view container logs. DEBUG logs are generated.

  • Remember to set the log level back after viewing the logINFOLevel.
logger -c 21b8d17c --name ROOT --level info
Copy the code

sc

View information about classes that have been loaded into the JVM, short for search-class.

  • searchcom.macro.mallAll classes under the package;
sc com.macro.mall.*
Copy the code

  • Print the class details and add-dArgument and specify the fully qualified class name;
sc -d com.macro.mall.tiny.common.api.CommonResult
Copy the code

  • Print out the Field information for the class using-fParameters.
sc -d -f com.macro.mall.tiny.common.api.CommonResult
Copy the code

sm

View the Method information of the loaded class, short for search-method. Search for the Method information of all loaded classes.

  • View all the methods in the class;
sm com.macro.mall.tiny.common.api.CommonResult
Copy the code

  • To view the specified method information, use-dParameter and specify the method name;
sm -d com.macro.mall.tiny.common.api.CommonResult getCode
Copy the code

jad

Decompile loaded class source code, feel online code and expected inconsistent, can decompile look.

  • View information about the startup class, which is provided by defaultClassLoaderInformation;
jad com.macro.mall.tiny.MallTinyApplication
Copy the code

  • use--source-onlyParameter can print only class information.
jad --source-only com.macro.mall.tiny.MallTinyApplication
Copy the code

mc

Memory Compiler, short for Memory Compiler, compiles.java files to generate.class.

redefine

Load an external. Class file that overwrites classes already loaded in the JVM.

monitor

You can monitor method execution information in real time, such as the time when a method is successfully executed, number of failures, and average time taken.

monitor -c 5 com.macro.mall.tiny.controller.PmsBrandController listBrand
Copy the code

watch

Method performs data observation, which allows you to observe the parameters and return values of a method during its execution.

Observe the execution parameters and return values of the method using the following command, where -x indicates the traversal depth of the result attribute.

watch com.macro.mall.tiny.service.impl.PmsBrandServiceImpl listBrand "{params,returnObj}" -x 2
Copy the code

Hot update

While it’s not always a good idea to have hot code online, there are times when you really need hot code. Here’s how to hot update code using JAD/MC/RE-define.

  • First we have an interface for item details when we pass inid<=0Is thrownIllegalArgumentException;
/** * Controller * Created by macro on 2019/4/19. */
@Api(tags = "PmsBrandController", description = "Product Brand Management")
@Controller
@RequestMapping("/brand")
public class PmsBrandController {
    @Autowired
    private PmsBrandService brandService;

    private static final Logger LOGGER = LoggerFactory.getLogger(PmsBrandController.class);

    @ApiOperation("Get brand details for the specified ID")
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<PmsBrand> brand(@PathVariable("id") Long id) {
        if(id<=0) {throw new IllegalArgumentException("id not excepted id:"+id);
        }
        returnCommonResult.success(brandService.getBrand(id)); }}Copy the code
  • Call interface returns the following information, call the address: http://192.168.5.94:8088/brand/0
{
  "timestamp": "The 2020-06-12 T06: he. 951 + 0000"."status": 500."error": "Internal Server Error"."message": "id not excepted id:0"."path": "/brand/0"
}
Copy the code
  • We would like to fix the problem if passedid<=0, directly returns null dataCommonResult, the code modification is as follows;
/** * Controller * Created by macro on 2019/4/19. */
@Api(tags = "PmsBrandController", description = "Product Brand Management")
@Controller
@RequestMapping("/brand")
public class PmsBrandController {
    @Autowired
    private PmsBrandService brandService;

    private static final Logger LOGGER = LoggerFactory.getLogger(PmsBrandController.class);
    
    @ApiOperation("Get brand details for the specified ID")
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<PmsBrand> brand(@PathVariable("id") Long id) {
        if(id<=0) {// throw new IllegalArgumentException("id not excepted id:"+id);
            return CommonResult.success(null);
        }
        returnCommonResult.success(brandService.getBrand(id)); }}Copy the code
  • First of all we need to get rightPmsBrandControllerModify the class code, then upload it to the server, and use the following command tojavaFile copied to container/tmpDirectory;
docker container cp /tmp/PmsBrandController.java mall-tiny-arthas:/tmp/
Copy the code
  • Then we need to look at the Hash value of the class loader for that class;
sc -d *PmsBrandController | grep classLoaderHash
Copy the code

  • Then use an in-memory compiler to make the changes.javaFile compiled into.classFile, note that it needs to be used-cSpecify a class loader;
mc -c 21b8d17c /tmp/PmsBrandController.java -d /tmp
Copy the code

  • Finally usingredefineThe command to load.classFile, which overwrites the originally loaded class;
redefine -c 21b8d17c /tmp/com/macro/mall/tiny/controller/PmsBrandController.class
Copy the code

  • We once again call interface test, found that has returned to the expected result, call address: http://192.168.3.101:8088/brand/0
{
  "code": 200."message": "Operation successful"."data": null
}
Copy the code

The resources

The official document: alibaba. Making. IO/arthas

Project source code address

Github.com/macrozheng/…

The public,

Mall project full set of learning tutorials serialized, attention to the public number the first time access.