Activiti工作流会签一 部署流程

2024-06-04 03:38

本文主要是介绍Activiti工作流会签一 部署流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这里使用的方式是和springboot整合的activiti工作流5.22.0版。 并且是在线编辑流程图
的,关于整合请自动百度,我应该在后面也会写一篇文章。

创建模型

ActModelController.java

首先在自定义的controller类中注册下面两个Bean对象:
repositoryService的主要作用是管理流程仓库,例如部署,删除。 repositoryService详细介绍
ObjectMapper 是fastjson的Bean,主要作用是对一些内容进行json转化。

    @AutowiredRepositoryService repositoryService;@AutowiredObjectMapper objectMapper;
 @RequestMapping(value = "/add", method = RequestMethod.POST)@ApiOperation(value = "创建新模型")public Result<Object> addModel(ActModel actModel){// 初始化一个空模型Model model = repositoryService.newModel();ObjectNode modelNode = objectMapper.createObjectNode();modelNode.put(ModelDataJsonConstants.MODEL_NAME, actModel.getName());modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, actModel.getDescription());modelNode.put(ModelDataJsonConstants.MODEL_REVISION, model.getVersion());model.setName(actModel.getName());model.setKey(actModel.getModelKey());model.setMetaInfo(modelNode.toString());// 保存模型repositoryService.saveModel(model);String id = model.getId();// 完善ModelEditorSourceObjectNode editorNode = objectMapper.createObjectNode();ObjectNode stencilSetNode = objectMapper.createObjectNode();ObjectNode properties = objectMapper.createObjectNode();stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");editorNode.replace("stencilset", stencilSetNode);properties.put("process_id", actModel.getModelKey());editorNode.replace("properties", properties);try {repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));} catch (UnsupportedEncodingException e) {log.error(e.toString());return ResultUtil.error("添加模型失败");}// 保存扩展模型至数据库actModel.setId(id);actModel.setVersion(model.getVersion());actModelService.save(actModel);return ResultUtil.success("添加模型成功");}

把模型名称, 标型存到自行创建的表中,方便管理,查询。

@Data
@TableName("t_act_model")
@ApiModel(value = "模型")
public class ActModel extends TbootBaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "模型名称")private String name;@ApiModelProperty(value = "标识")private String modelKey;@ApiModelProperty(value = "版本")private Integer version;@ApiModelProperty(value = "描述/备注")private String description;
}

会签画图

会签 : 多个人,同时批准才能进入到下一步流程。

这是一个简单的会签图

这是一个简单的会签图, 下面我们会简单的说一下会签的画图流程。

在这里插入图片描述

画完流程图,对流程图进行保存

public class ModelSaveRestResource implements ModelDataJsonConstants

引入三个bean
ActModelService 为我们自己定义的业务的bean,其他两个上面已经介绍过了。

@Autowiredprivate RepositoryService repositoryService;@Autowiredprivate ObjectMapper objectMapper;@Autowiredprivate ActModelService actModelService;

下面就是就model进行更新了, 我们需要把画的流程图定义以json的格式和流程图片转成的字节码存储到工作流中。可以使用 repositoryService.addModelEditorSource(model.getId(), json_xml.getBytes("utf-8"));
repositoryService.addModelEditorSourceExtra(model.getId(), result);

@RequestMapping(value="/model/{modelId}/save", method = RequestMethod.PUT)@ResponseStatus(value = HttpStatus.OK)public void saveModel(@PathVariable String modelId,@RequestParam String name, @RequestParam String description,@RequestParam String json_xml, @RequestParam String svg_xml) {try {Model model = repositoryService.getModel(modelId);ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo());int newVersion = model.getVersion()+1;modelJson.put(MODEL_NAME, name);modelJson.put(MODEL_DESCRIPTION, description);modelJson.put(MODEL_REVISION, newVersion);model.setMetaInfo(modelJson.toString());model.setName(name);model.setVersion(newVersion);repositoryService.saveModel(model);repositoryService.addModelEditorSource(model.getId(), json_xml.getBytes("utf-8"));InputStream svgStream = new ByteArrayInputStream(svg_xml.getBytes("utf-8"));TranscoderInput input = new TranscoderInput(svgStream);PNGTranscoder transcoder = new PNGTranscoder();// Setup outputByteArrayOutputStream outStream = new ByteArrayOutputStream();TranscoderOutput output = new TranscoderOutput(outStream);// Do the transformationtranscoder.transcode(input, output);final byte[] result = outStream.toByteArray();repositoryService.addModelEditorSourceExtra(model.getId(), result);outStream.close();// 更新数据库ActModel actModel = actModelService.getById(modelId);// 更新keyString key = StrUtil.subBetween(json_xml, "\"process_id\":\"", "\",\"name\"");actModel.setModelKey(key);actModel.setName(name);actModel.setDescription(description);actModel.setVersion(newVersion);actModelService.updateById(actModel);} catch (Exception e) {log.error("保存模型出错", e);throw new ActivitiException("保存模型出错", e);}}

到此为止,我们就定义了一个工作流的模型, 这个模型包括基本的名称,key,版本号,工作流程定义,工作流程图片。现在我们只是定义了一个模型,还是无法使用。下面要把模型部署。

模型部署

下面就开始部署模型了,只有部署过的模型才会被创建一个工作流。部署过的模型,是可以在更改的,但是需要重新部署才会影响到已经部署的模型。

模型部署的接口我们可以新创建一个controller, 定义一个方法接收模型ID。

ActModelController.java

引入bean

RepositoryService 仍然是上面我们提到过的activiti自带的bean对象,ObjectMapper 同样是fastjson提供的Bean.

    @AutowiredRepositoryService repositoryService;@AutowiredObjectMapper objectMapper;

下面是方法接口, 我们第一步:获取模型,模型的内容,是我们在上面的方法,创建模型和保存模型内容的时候调用ACITIVITI的API,添加到ACITIVITI自带的表中的。 这里我们可以直接调用API获取出来。

第二步:将定义的流程转换成BpmnModel字节数组, 里面所有转换工具基本都是acitiviti提供的。
第三步—第五步,可以看代码中的注释。

@RequestMapping(value = "/deploy/{id}", method = RequestMethod.GET)@ApiOperation(value = "部署发布模型")public Result<Object> deploy(@PathVariable String id) {//第一步:  获取模型Model modelData = repositoryService.getModel(id);byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());if (bytes == null) {return ResultUtil.error("模型数据为空,请先成功设计流程并保存");}try {
//            第二步,将定义的流程转换成BpmnModel字节数组JsonNode modelNode = new ObjectMapper().readTree(bytes);BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);if(model.getProcesses().size()==0){return ResultUtil.error("模型不符要求,请至少设计一条主线流程");}byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);//第三步: 部署发布模型流程String processName = modelData.getName() + ".bpmn20.xml";Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes, "UTF-8")).deploy();// 第四步: 设置流程分类 保存扩展流程至数据库List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).list();// 第五步: 将流程定义的内容保存至本地数据库中一份,主要是因为方便业务开发的时候进行查询展示管理。ActModel actModel = actModelService.getById(id);for (ProcessDefinition pd : list) {ActProcess actProcess = new ActProcess();actProcess.setId(pd.getId());actProcess.setName(modelData.getName());actProcess.setProcessKey(modelData.getKey());actProcess.setDeploymentId(deployment.getId());actProcess.setDescription(actModel.getDescription());actProcess.setVersion(pd.getVersion());actProcess.setXmlName(pd.getResourceName());actProcess.setDiagramName(pd.getDiagramResourceName());actProcessService.setAllOldByProcessKey(modelData.getKey());actProcess.setLatest(true);actProcessService.saveOrUpdate(actProcess);}}catch (Exception e){log.error(e.toString());return ResultUtil.error("部署失败");}return ResultUtil.success("部署成功");}

第五步我们是使用自己项目中的API将数据保存到自己创建的表中了。 下面帖出自己创建的对象,可以参照对象建表。

@Data
@TableName("t_act_process")
@ApiModel(value = "流程定义")
public class ActProcess extends TbootBaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "流程名称")private String name;@ApiModelProperty(value = "流程标识名称")private String processKey;@ApiModelProperty(value = "版本")private Integer version;@ApiModelProperty(value = "部署id")private String deploymentId;@ApiModelProperty(value = "所属分类")private String categoryId;@ApiModelProperty(value = "xml文件名")private String xmlName;@ApiModelProperty(value = "流程图片名")private String diagramName;@ApiModelProperty(value = "描述/备注")private String description;@ApiModelProperty(value = "最新版本")private Boolean latest;@ApiModelProperty(value = "流程状态 部署后默认1激活")private Integer status = ActivitiConstant.PROCESS_STATUS_ACTIVE;@ApiModelProperty(value = "关联前端表单路由名")private String routeName;@ApiModelProperty(value = "关联业务表名")private String businessTable;@ApiModelProperty(value = "是否所有人可见")private Boolean allUser;@ApiModelProperty(value = "所属分类名称")private String categoryTitle;
}

流程部署是完成了,但是还有一个比较重要的工作就是,节点的审批人还没有设置。 下面我们就要开始设计节点的审批人员。

给流程节点设置审批人员

如果我们要给流程节点设置审批人员,那么首先我们要获取两个要素,第一个就是流程节点,第二个就是人员。 人员是强自定义的业务,这里就不在介绍了。 下面我们主要是聊一聊流程节点。

业务流程是通过部署流程的ID sickLeave:6:27516 来获取包括详细定义流程的BpmnModel。 这个ID是系统自动拼接的,总共分三位: 第一位:是模型KEY,我们在模型创建的时候自已添加的,第二部分是部署的版本号,当我们在部署模型的时侯这个值会累加, 第三部分是系统自动添加的。

我们获取BpmnModel之后就可以获取里面的节点了。 可以开发一个接口来专门获取里面的节点信息。

ActProcessController

	@RequestMapping(value = "/getProcessNode/{id}", method = RequestMethod.GET)@ApiOperation(value = "通过流程定义id获取流程节点")public Result<List<ProcessNodeVo>> getProcessNode(@ApiParam("流程定义id") @PathVariable String id){// 第一步: 获取Bpmn流程BpmnModel bpmnModel = repositoryService.getBpmnModel(id);List<ProcessNodeVo> list = new ArrayList<>();// 第二步: 获取BPMN中的流程List<Process> processes = bpmnModel.getProcesses();if(processes==null||processes.size()==0){return new ResultUtil<List<ProcessNodeVo>>().setData(null);}for(Process process : processes){// 对流程中的每一个节点进行遍历 获取里面的信息Collection<FlowElement> elements = process.getFlowElements();for(FlowElement element : elements){ProcessNodeVo node = new ProcessNodeVo();node.setId(element.getId());node.setTitle(element.getName());if(element instanceof StartEvent){// 开始节点node.setType(ActivitiConstant.NODE_TYPE_START);// 设置关联用户node.setUsers(actNodeService.findUserByNodeId(id));// 设置关联角色node.setRoles(actNodeService.findRoleByNodeId(id));// 设置关联部门node.setDepartments(actNodeService.findDepartmentByNodeId(id));}else if(element instanceof UserTask){// 用户任务node.setType(ActivitiConstant.NODE_TYPE_TASK);// 设置关联用户node.setUsers(actNodeService.findUserByNodeId(element.getId()));// 设置关联角色node.setRoles(actNodeService.findRoleByNodeId(element.getId()));// 设置关联部门node.setDepartments(actNodeService.findDepartmentByNodeId(element.getId()));// 是否设置操作人负责人node.setChooseDepHeader(actNodeService.hasChooseDepHeader(element.getId()));// 是否设置操作人负责人node.setCustomUser(actNodeService.hasCustomUser(element.getId()));}else if(element instanceof EndEvent){// 结束node.setType(ActivitiConstant.NODE_TYPE_END);}else{// 排除其他连线或节点continue;}list.add(node);}}return new ResultUtil<List<ProcessNodeVo>>().setData(list);}

这里面有两个项目中自定义的包装类,主要用于给前端包装显示使用的。

@Data
@Accessors(chain = true)
@TableName("t_act_node")
@ApiModel(value = "节点")
public class ActNode extends TbootBaseEntity {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "节点id")private String nodeId;@ApiModelProperty(value = "节点关联类型 0角色 1用户 2部门")private Integer type;@ApiModelProperty(value = "关联其他表id")private String relateId;}
package com.budongfeng.tboot.modules.activiti.vo;import com.budongfeng.tboot.modules.base.entity.Department;
import com.budongfeng.tboot.modules.base.entity.Role;
import com.budongfeng.tboot.modules.base.entity.User;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.List;/*** @author 田培融*/
@Data
public class ProcessNodeVo {@ApiModelProperty(value = "节点id")private String id;@ApiModelProperty(value = "节点名")private String title;@ApiModelProperty(value = "节点类型 0开始 1用户任务 2结束 3排他网关")private Integer type;@ApiModelProperty(value = "关联角色")private List<Role> roles;@ApiModelProperty(value = "关联用户")private List<User> users;@ApiModelProperty(value = "关联部门")private List<Department> departments;@ApiModelProperty(value = "多级连续部门负责人")private Boolean chooseDepHeader = false;@ApiModelProperty(value = "自选用户")private Boolean customUser = false;@ApiModelProperty(value = "节点展开 前端所需")private Boolean expand = true;
}

流程的结束也是不同的,我们做了一个简单的区别。 下面就可以给节点添加用户了。 这里我们定义了两个接口,第一个修改流程定义的分类。 这里其实是可以不用配置的,只是为了代码的完善, 后续的查询。

 @RequestMapping(value = "/updateInfo", method = RequestMethod.POST)@ApiOperation(value = "修改关联路由表单分类或备注")public Result<Object> updateInfo(ActProcess actProcess){ActProcess old = actProcessService.getById(actProcess.getId());if(old==null){return ResultUtil.error("流程信息不存在");}ProcessDefinition pd = repositoryService.getProcessDefinition(actProcess.getId());if(pd==null){return ResultUtil.error("流程定义不存在");}PageUtil.SQLInject(actProcess.getBusinessTable());repositoryService.setProcessDefinitionCategory(actProcess.getId(), actProcess.getCategoryId());repositoryService.setDeploymentCategory(pd.getDeploymentId(), actProcess.getCategoryId());old.setRouteName(actProcess.getRouteName());old.setBusinessTable(actProcess.getBusinessTable());old.setDescription(actProcess.getDescription());if(StrUtil.isNotBlank(actProcess.getCategoryId())){ActCategory c = actCategoryService.getById(actProcess.getCategoryId());if(c!=null){old.setCategoryId(actProcess.getCategoryId());old.setCategoryTitle(c.getTitle());}}else{old.setCategoryId(null);old.setCategoryTitle("");}actProcessService.updateById(old);return ResultUtil.data("修改成功");}

关于上面的代码,repositoryService这个API的相关操作是Activiti工作流相关的,其他的是我们自己开发的。

我们可以先设置谁能发起这个流程,后面我们在设置谁能处理这个节点。 这里面的代码和工作流API没有关系 。纯属业务代码, 因此就不在详细介绍了。

    @RequestMapping(value = "/editStartUser", method = RequestMethod.POST)@ApiOperation(value = "编辑流程可发起用户")public Result<Object> editStartUser(@ApiParam("流程定义id") @RequestParam String nodeId,@ApiParam("是否所有用户可见") @RequestParam Boolean allUser,@RequestParam(required = false) String[] userIds,@RequestParam(required = false) String[] roleIds,@RequestParam(required = false) String[] departmentIds){// 删除其关联权限actNodeService.deleteByNodeId(nodeId);actStarterService.deleteByProcessDefId(nodeId);ActProcess actProcess = actProcessService.getById(nodeId);if(actProcess==null){return ResultUtil.error("流程不存在");}actProcess.setAllUser(allUser);actProcessService.updateById(actProcess);if(!allUser){HashSet<String> starters = new HashSet<>();List<ActStarter> listStarter = new ArrayList<>();List<ActNode> listNode = new ArrayList<>();// 分配新用户if(userIds!=null){for(String userId : userIds){// 保存用户if(!starters.contains(userId)){ActStarter actStarter = new ActStarter().setProcessDefId(nodeId).setUserId(userId);listStarter.add(actStarter);starters.add(userId);}// 保存配置ActNode actNode = new ActNode().setNodeId(nodeId).setRelateId(userId).setType(ActivitiConstant.NODE_USER);listNode.add(actNode);}}// 分配新角色的用户if(roleIds!=null){for(String roleId : roleIds){// 通过角色获取用户List<UserRole> userRoles = userRoleService.findByRoleId(roleId);for (UserRole ur : userRoles){// 保存用户if(!starters.contains(ur.getUserId())){ActStarter actStarter = new ActStarter().setProcessDefId(nodeId).setUserId(ur.getUserId());listStarter.add(actStarter);starters.add(ur.getUserId());}}ActNode actNode = new ActNode().setNodeId(nodeId).setRelateId(roleId).setType(ActivitiConstant.NODE_ROLE);listNode.add(actNode);}}// 分配新部门if(departmentIds!=null){for(String departmentId : departmentIds){// 通过部门获取用户List<User> users = userService.findByDepartmentId(departmentId);for (User u : users){// 保存用户if(!starters.contains(u.getId())){ActStarter actStarter = new ActStarter().setProcessDefId(nodeId).setUserId(u.getId());listStarter.add(actStarter);starters.add(u.getId());}};ActNode actNode = new ActNode().setNodeId(nodeId).setRelateId(departmentId).setType(ActivitiConstant.NODE_DEPARTMENT);listNode.add(actNode);}}// 批量保存actStarterService.saveOrUpdateBatch(listStarter);actNodeService.saveOrUpdateBatch(listNode);// GCstarters = null;}return ResultUtil.success("操作成功");}@RequestMapping(value = "/editNodeUser", method = RequestMethod.POST)@ApiOperation(value = "编辑节点分配用户")public Result<Object> editNodeUser(@RequestParam String nodeId,@RequestParam(required = false) String[] userIds,@RequestParam(required = false) String[] roleIds,@RequestParam(required = false) String[] departmentIds,@ApiParam("是否勾选操连续多级部门负责人") @RequestParam(required = false) Boolean chooseDepHeader,@ApiParam("是否勾选用户自选") @RequestParam(required = false) Boolean customUser){// 删除其关联数据actNodeService.deleteByNodeId(nodeId);if(customUser!=null&&customUser){ActNode actNode = new ActNode().setNodeId(nodeId).setType(ActivitiConstant.NODE_CUSTOM);actNodeService.save(actNode);return ResultUtil.success("操作成功");}List<ActNode> list = new ArrayList<>();// 分配新用户if(userIds!=null){for(String userId : userIds){ActNode actNode = new ActNode().setNodeId(nodeId).setRelateId(userId).setType(ActivitiConstant.NODE_USER);list.add(actNode);}}// 分配新角色if(roleIds!=null){for(String roleId : roleIds){ActNode actNode = new ActNode().setNodeId(nodeId).setRelateId(roleId).setType(ActivitiConstant.NODE_ROLE);list.add(actNode);}}// 分配新部门if(departmentIds!=null){for(String departmentId : departmentIds){ActNode actNode = new ActNode().setNodeId(nodeId).setRelateId(departmentId).setType(ActivitiConstant.NODE_DEPARTMENT);list.add(actNode);}}if(chooseDepHeader!=null&&chooseDepHeader){ActNode actNode = new ActNode().setNodeId(nodeId).setType(ActivitiConstant.NODE_DEP_HEADER);list.add(actNode);}// 批量保存actNodeService.saveOrUpdateBatch(list);return ResultUtil.success("操作成功");}

到此工作流的会签算是完成了。 部署完成了,下面我会在写一篇文章来介绍,关于启动一个工作流,到工作流结束的流程。还是会使用这个会签的案例。

猿来衣舍

这是博主开的淘宝小店,主要经营舒适保暖的服饰,有袜子、主题卫衣、保暖衣。欢迎大家选购。

TEngine java开发脚手架

测试账号 test 123456

我这个脚手架目前是做为店铺福利送给顾客的,联系客服获取

猿来衣舍
猿来衣舍
猿来衣舍
猿来衣舍

打开淘宝搜索 “猿来衣舍”这四个字就可以搜到小店,希望大家多多支持。

一个人能够走多远,关键在于与谁同行,我用跨越山海的一路相伴,希望得到您用金钱的称赞。

这篇关于Activiti工作流会签一 部署流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1028956

相关文章

闲置电脑也能活出第二春?鲁大师AiNAS让你动动手指就能轻松部署

对于大多数人而言,在这个“数据爆炸”的时代或多或少都遇到过存储告急的情况,这使得“存储焦虑”不再是个别现象,而将会是随着软件的不断臃肿而越来越普遍的情况。从不少手机厂商都开始将存储上限提升至1TB可以见得,我们似乎正处在互联网信息飞速增长的阶段,对于存储的需求也将会不断扩大。对于苹果用户而言,这一问题愈发严峻,毕竟512GB和1TB版本的iPhone可不是人人都消费得起的,因此成熟的外置存储方案开

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

工作常用指令与快捷键

Git提交代码 git fetch  git add .  git commit -m “desc”  git pull  git push Git查看当前分支 git symbolic-ref --short -q HEAD Git创建新的分支并切换 git checkout -b XXXXXXXXXXXXXX git push origin XXXXXXXXXXXXXX

在 Windows 上部署 gitblit

在 Windows 上部署 gitblit 在 Windows 上部署 gitblit 缘起gitblit 是什么安装JDK部署 gitblit 下载 gitblit 并解压配置登录注册为 windows 服务 修改 installService.cmd 文件运行 installService.cmd运行 gitblitw.exe查看 services.msc 缘起

嵌入式方向的毕业生,找工作很迷茫

一个应届硕士生的问题: 虽然我明白想成为技术大牛需要日积月累的磨练,但我总感觉自己学习方法或者哪些方面有问题,时间一天天过去,自己也每天不停学习,但总感觉自己没有想象中那样进步,总感觉找不到一个很清晰的学习规划……眼看 9 月份就要参加秋招了,我想毕业了去大城市磨练几年,涨涨见识,拓开眼界多学点东西。但是感觉自己的实力还是很不够,内心慌得不行,总怕浪费了这人生唯一的校招机会,当然我也明白,毕业

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除

Solr部署如何启动

Solr部署如何启动 Posted on 一月 10, 2013 in:  Solr入门 | 评论关闭 我刚接触solr,我要怎么启动,这是群里的朋友问得比较多的问题, solr最新版本下载地址: http://www.apache.org/dyn/closer.cgi/lucene/solr/ 1、准备环境 建立一个solr目录,把solr压缩包example目录下的内容复制

husky 工具配置代码检查工作流:提交代码至仓库前做代码检查

提示:这篇博客以我前两篇博客作为先修知识,请大家先去看看我前两篇博客 博客指路:前端 ESlint 代码规范及修复代码规范错误-CSDN博客前端 Vue3 项目开发—— ESLint & prettier 配置代码风格-CSDN博客 husky 工具配置代码检查工作流的作用 在工作中,我们经常需要将写好的代码提交至代码仓库 但是由于程序员疏忽而将不规范的代码提交至仓库,显然是不合理的 所