Operations 9 min read

Design and Implementation of ZuanZuan Server‑Side Environment Maintenance Program (Agent + CMD)

The article presents a comprehensive overview of ZuanZuan's server‑side environment maintenance system, detailing its agent‑cmd architecture, modular directory structure, Python‑based script redesign, execution‑list assembly, reflection‑driven method invocation, termination callbacks, plugin‑style modules, utility functions for services like Nginx, and an interactive console tool for streamlined operations.

转转QA
转转QA
转转QA
Design and Implementation of ZuanZuan Server‑Side Environment Maintenance Program (Agent + CMD)

The ZuanZuan server‑side environment maintenance program follows an agent + cmd model where the Agent handles remote command interaction and scheduling, while the Cmd component executes specific maintenance scripts on the server.

The CMD module consists of five main parts: script (core operations such as sync, deploy, recycle, etc.), module (generic plugins like replace and check), config (constants), util (wrappers for shell, ftp, nginx, http, mail, etc.), and console (a Python‑based command‑menu tool).

The project directory tree is organized as follows:

.
├── agent   // agent part
├── config
├── console
├── doc      // documentation
├── install  // one‑click install resources
├── log      // logging module
├── modules
├── script
├── test     // unit‑test scripts
└── util

Script redesign addresses common problems of traditional shell scripts—poor readability, high maintenance cost, tangled logic, difficult debugging, and tight coupling. The team switched to Python, resulting in fewer lines, faster updates, and better traceability.

To make execution steps flexible, they assemble a list of steps that can be added, removed, or reordered without modifying code logic:

list = ['step1', 'step2', 'step3', 'step5', 'step4']

Another example of a concrete to‑do list:

self.to_do_list = ['cluster_info', 'down_ftp', 'kill_wf', 'replace_wf', 'check_wf', 'deploy_wf', 'start_wf']

In the base CMD class, Python reflection is used to invoke methods dynamically:

def __DO__(self, method_name):
    PrintFormatUtil.print_line("----- 开始执行" + self.__class__.__name__ + "." + method_name + "()")
    start = time.time()
    m = getattr(self, method_name)
    m()
    end = time.time()
    PrintFormatUtil.print_line("----- 执行结束,耗时:" + str(round((end - start), 2)) + "(s)")

Termination callbacks are handled with Python's atexit library to guarantee cleanup actions even on abnormal exits:

atexit.register(exit_to_do, task_id, task_pid, 'restartwf')

Module design follows a plugin architecture for reusable services such as identity checks, replace rules, and validation strategies. Example of constructing a replace‑rule plugin:

ReplaceRules().replace_rules(env_type, self.product_line, "%s/config" % self.source_path, cluster_name)

Configuration strategies are expressed as dictionaries, e.g.:

check_list = {"jar_version_check": "1"  # 1: force block, 2: error no block, 3: warning}

File‑replacement logic uses regex patterns:

self.replace_file_by_regex(f_p, [".*\.conf", ".*\.properties"], ["http://zhuanzhuan.58.com", "http://zhuan.58.com", "http://www.zhuanzhuan.com"], 'http://' + domain)

Util design centralizes common service commands, such as Nginx operations, certificate handling, and interactive Expect scripts. Sample snippets include:

spawn $PATH -delete -alias $ALIAS -keystore $KEYTORE -file /opt/soft/sso.test.58.com.crt -storepass changeit
expect {
    "Trust*" {send "y\r"; exp_continue}
    "信任*" {send "y\r"; exp_continue}
    "是否信任*" {send "y\r"; exp_continue}
}

Real‑time log handling is implemented by tracking file offsets and using tail to fetch incremental lines:

while time.mktime(datetime.datetime.now().timetuple()) - start_stamp < time_out:
    output = ''
    sleep(1)
    log_end_line = ShellUtil.get_file_line(self.module_log)
    line_diff = log_end_line - log_start_line
    if line_diff != 0:
        self.print_info("日志地址 %s,日志增加偏移量 %s 行" % (self.module_log, line_diff))
        return_code, output, er = ShellUtil.shell_cmd("tail -n %s %s" % (line_diff, self.module_log))
        PrintFormatUtil.print_multi_line(output)
        self.push_log(0, self.t_tid, output)
    try:
        ...
    except Exception as er:
        ...

Console design provides an integrated, server‑side visual command menu tool that runs without leaving the server, offers interactive operations, pagination, and quick switching between commands (e.g., invoking the console with the zz command).

backendPythonOperationsmodular architectureServer AutomationScript Design
转转QA
Written by

转转QA

In the era of knowledge sharing, discover 转转QA from a new perspective.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.