5.modelHandler处理model

一、前言

前面的文章主要介绍了logback将logback.xml中的节点路径解析成一个个的model, 最后在DefaultProcessor中使用modelHandler对model进行处理, 本节将介绍几个常用标签节点的modelHandler解析的详细过程

二、常用modelHandler解析model

configuration标签解析

configuration节点对应的是ConfigurationModel, 使用ConfigurationModelHandlerFull解析, ConfigurationModelHandlerFull继承了ConfigurationModelHandler类, 我们先看一下ConfigurationModelHandler

public class ConfigurationModelHandler extends ModelHandlerBase {
   
   
    ConfigurationModel configurationModel = (ConfigurationModel) model;

        // See LOGBACK-527 (the system property is looked up first). Thus, it overrides
        // the equivalent property in the config file. This reversal of scope priority
        // is justified by the use case: the admin trying to chase rogue config file
        // 1.debug属性系统; 属性中获取 logback.debug
        String debugAttrib = OptionHelper.getSystemProperty(DEBUG_SYSTEM_PROPERTY_KEY, null);
        if (debugAttrib == null) {
   
   
            // configuration的debug属性
            debugAttrib = mic.subst(configurationModel.getDebugStr());
        }
        
        // 1.logback.debug不是空 2并且不是非false 3并且不是null字符串
        if (!(OptionHelper.isNullOrEmptyOrAllSpaces(debugAttrib) || debugAttrib.equalsIgnoreCase(FALSE.toString())
                || debugAttrib.equalsIgnoreCase(NULL_STR))) {
   
   
            // 添加OnConsoleStatusListener监听器, 并打印状态
            StatusListenerConfigHelper.addOnConsoleListenerInstance(context, new OnConsoleStatusListener());
        }
        // 查询scan属性, 非false的话打印日志
        processScanAttrib(mic, configurationModel);

        LoggerContext lc = (LoggerContext) context;
        // packagingData属性, 用于打印打包信息, 默认是false
        boolean packagingData = OptionHelper.toBoolean(mic.subst(configurationModel.getPackagingDataStr()),
                LoggerContext.DEFAULT_PACKAGING_DATA);
        lc.setPackagingDataEnabled(packagingData);

        ContextUtil contextUtil = new ContextUtil(context);
        contextUtil.addGroovyPackages(lc.getFrameworkPackages());
}

方法小结

  1. 这个方法解析了configuration标签的debug属性和scan属性和packagingData属性
  2. debug属性为true的话, 将会添加一个OnConsoleStatusListener监听器, 打印logback日志框架启动时的一些日志
  • 可以使用-Dlogback.debug设置系统级参数来控制, 它的优先级比configuration标签的debug属性还要高
  1. scan属性, 如果开启的话, 将会监听日志配置文件, 可以用来动态修改日志等级
  2. packagingData属性, 如果为true, 将会打印打包相关的日志

ConfigurationModelHandlerFull

public class ConfigurationModelHandlerFull extends ConfigurationModelHandler {
   
   
    
    protected void postProcessScanAttrib(ModelInterpretationContext mic, ConfigurationModel configurationModel) {
   
   
        // scan属性
        String scanStr = mic.subst(configurationModel.getScanStr());
        // scanPeriod属性
        String scanPeriodStr = mic.subst(configurationModel.getScanPeriodStr());
        detachedPostProcess(scanStr, scanPeriodStr);
    }
    
    public void detachedPostProcess(String scanStr, String scanPeriodStr) {
   
   
        // scan 非false, 一般可以设置scan为true
        if (!OptionHelper.isNullOrEmptyOrAllSpaces(scanStr) && !"false".equalsIgnoreCase(scanStr)) {
   
   
            // 默认是ScheduledThreadPoolExecutor类, 核心线程是4个
            ScheduledExecutorService scheduledExecutorService = context.getScheduledExecutorService();
            // 1.校验热加载文件;动态监听的配置文件, 默认是监听logback.xml文件, 所以默认是true
            // 可以使用configuration/propertiesConfigurator节点来指定热加载的文件
            boolean watchPredicateFulfilled = ConfigurationWatchListUtil.watchPredicateFulfilled(context);
            if (!watchPredicateFulfilled) {
   
   
                addWarn(FAILED_WATCH_PREDICATE_MESSAGE_1);
                addWarn(FAILED_WATCH_PREDICATE_MESSAGE_2);
                return;
            }
            // 2.创建周期任务, 可以用来动态修改日志等级
            ReconfigureOnChangeTask rocTask = new ReconfigureOnChangeTask();
            rocTask.setContext(context);

            addInfo("Registering a new ReconfigureOnChangeTask " + rocTask);
            // 3.发布热加载对象注册事件
    context.fireConfigurationEvent(ConfigurationEvent.newConfigurationChangeDetectorRegisteredEvent(rocTask));

            // 扫描间隔 scanPeriod 默认是1min; 格式 '数字 单位'
            Duration duration = getDurationOfScanPeriodAttribute(scanPeriodStr, SCAN_PERIOD_DEFAULT);

            addInfo("Will scan for changes in [" + ConfigurationWatchListUtil.getConfigurationWatchList(context) + "] ");
            addInfo("Setting ReconfigureOnChangeTask scanning period to " + duration);

            // 4.执行周期任务
            ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(rocTask, duration.getMilliseconds(), duration.getMilliseconds(),
                            TimeUnit.MILLISECONDS);
            rocTask.setScheduredFuture(scheduledFuture);
            context.addScheduledFuture(scheduledFuture);
        }

    }
}

方法小结

  1. configuration标签的scan=true用来开启热加载扫描文件
  2. 默认热加载的文件是logback.xml, 可以通过configuration/propertiesConfigurator标签添加热加载的文件, 只支持添加properties后缀和网络地址的文件
  3. 使用4个核心的周期执行器执行扫描任务, 任务对象是ReconfigureOnChangeTask
  4. 默认是一分钟扫描一次, 可以通过configuration标签的scanPeriod属性置顶执行周期, 例如 scanPeriod="5 minute", 单位可选为milli(或millisecond)、second(或seconde)、minute、hour、day

ReconfigureOnChangeTask热加载配置文件

public class ReconfigureOnChangeTask extends ContextAwareBase implements Runnable {
   
   
    public void run() {
   
   
        // 1.发布热加载运行事件
        context.fireConfigurationEvent(newConfigurationChangeDetectorRunningEvent(this));
        // 2.获取热加载需要扫描的文件们
        ConfigurationWatchList configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(context);
        if (configurationWatchList == null) {
   
   
            addWarn("Empty ConfigurationWatchList in context");
            return;
        }
        if (configurationWatchList.emptyWatchLists()) {
   
   
            addInfo("Both watch lists are empty. Disabling ");
            return;
        }
        // 3.获取热加载的本地文件
        File changedFile = configurationWatchList.changeDetectedInFile();
        <
5. 使用TorchServe部署PyTorch模型\nTorchServe是一个灵活的工具,用于部署和服务PyTorch模型。\n\n📝 5.1 导出PyTorch模型\n在训练阶段,将训练好的模型保存为TorchServe格式:\n\nimport torch\nimport torch.nn as nn\n\n# 假设我们已经训练好了一个模型\nclass MyModel(nn.Module):\n def __init__(self):\n super(MyModel, self).__init__()\n self.fc = nn.Linear(4, 3)\n\n def forward(self, x):\n return self.fc(x)\n\nmodel = MyModel()\ntorch.save(model.state_dict(), 'model.pth')\n\n# 定义模型的序列化和反序列化方法\nclass ModelHandler:\n def __init__(self):\n self.model = MyModel()\n self.model.load_state_dict(torch.load('model.pth'))\n self.model.eval()\n\n def handle(self, data):\n input_tensor = torch.tensor(data['features'])\n with torch.no_grad():\n output = self.model(input_tensor)\n return output.tolist()\n\n# 保存模型的序列化和反序列化方法\nimport json\nwith open('model_handler.py', 'w') as f:\n f.write(json.dumps({'model': 'model.pth', 'handler': 'model_handler.ModelHandler'}))\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n🔧 5.2 安装TorchServe\n在Linux上安装TorchServe:\n\npip3 install torch torchserve torch-model-archiver\n1\n🚀 5.3 运行TorchServe\n使用TorchServe启动模型服务:\n\ntorchserve --start --model-store model_store --models my_model=model_handler.mar\n1\n🔍 5.4 测试API\n使用curl命令测试API:\n\ncurl -X POST -H \"Content-Type: applicat更详细的步骤
06-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uncleqiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值