首页 文章 精选 留言 我的

精选列表

搜索[服务],共10000篇文章
优秀的个人博客,低调大师

袋鼠云代码检查服务,揭秘高质量代码背后的秘密

质量是产品的生命线,代码检查是软件开发过程中至关重要的一环,它可以帮助我们发现并纠正潜在的错误,提高软件质量,降低维护成本。 在袋鼠云产品中也存在这个问题,由于离线数据开发人员 SQL 水平不一,导致代码书写混乱、SQL 代码运行问题较多。本文将介绍在离线产品中如何利用 SQL 检查规则规范化 SQL 代码,对代码书写问题进行拦截,便于统一管理,用于预防引入需要治理的问题。 通过本文的介绍,我们希望您能够认识到代码检查的重要性,并了解如何通过最佳实践来提高代码质量和开发效率。 何时进行代码规则检查? SQL 任务在离线产品界面开发完成之后,点击运行的按钮,会先经过代码规则检查,如果代码规则不满足则会提示到用户具体的原因。 数据资产模块内置了 5 种代码检查规则,用户可以根据需要选择性开启。 开启后在离线项目管理中可以选择使用的代码规则检查项、生效范围和 SQL 任务类型。 在离线 SQL 任务中去运行一条 SQL 前会根据选择的规则先进行代码检查,如果代码检查不通过则会反馈给用户,用户可以根据实际需要判断要不要执行该 SQL。 在数据资产的代码检查时间中可以看到已经触发的检查历史以及相应的统计数据。 如何实现代码检查规则? 在 CodeCheck 包下定义了通用的代码规则检查的接口。 public interface ICheck { Result codeCheck(String checkContent, String defaultDb, Integer dataSourceType, Long tenantId, SqlParseInfo sqlParseInfo); CodeCheckType getCheckType(); } 以分区表查询必须带分区规则为例,会先调用 SQLParser 组件进行 SQL 解析,SQLParseInfo 即为 SQL 解析结果,检查时会先判断 SQL 语句是不是查询语句,如果是则判断查询的表是不是分区表,再判断是否有查询条件,最后判断查询条件中是否包含分区字段来判断是否检查通过。 public class CodeCheckImplType01 extends AbstractCheck { private static final Logger LOGGER = LoggerFactory.getLogger(CodeCheckImplType01.class); @Autowired private DataTableColumnThirdService dataTableColumnThirdService; @Autowired private DataTableThirdService dataTableThirdService; @Override public Result codeCheck(String checkContent, String defaultDb, Integer dataSourceType, Long tenantId, SqlParseInfo sqlParseInfo) { if (!isQuery(sqlParseInfo.getSqlType())) { return Result.buildSuccessResult(); } try { MetadataSearchParam searchParam = new MetadataSearchParam(); searchParam.setDbName(sqlParseInfo.getMainTable().getDb()); searchParam.setTableName(sqlParseInfo.getMainTable().getName()); searchParam.setDataSourceType(dataSourceType); searchParam.setTenantId(tenantId); List<TableDTO> tableDTOS = dataTableThirdService.tableList(searchParam); // 获取表信息 for (TableDTO tableDTO : tableDTOS) { List<DataTableColumn> tableColumns = dataTableColumnThirdService.listColumnByTableIds(Lists.newArrayList(tableDTO.getTableId())); if (CollectionUtils.isEmpty(tableColumns)) { continue; } List<String> partitionColumnNameList = tableColumns.stream() .filter(Objects::nonNull) .filter(t -> HavePartitionEnum.have_partition.getPartitionValue().equals(t.getIsPartition())) .map(DataTableColumn::getColumnName) .collect(Collectors.toList()); // 非分区表直接返回 if (CollectionUtils.isEmpty(partitionColumnNameList)) { continue; } if (CollectionUtils.isEmpty(sqlParseInfo.getColumnIdentifierList())) { // 没有查询条件则校验失败 return Result.buildFailedResult(String.format(getCheckType().getCheckResultFormat(), searchParam.getTableName())); } List<String> columnList = sqlParseInfo.getColumnIdentifierList().stream() .filter(c -> StringUtils.equals(c.getDb(), searchParam.getSchemaName()) && StringUtils.equals(c.getTable(), searchParam.getTableName())) .map(ColumnIdentifier::getColumn).collect(Collectors.toList()); boolean disjoint = Collections.disjoint(partitionColumnNameList, columnList); if (disjoint) { return Result.buildFailedResult(String.format(getCheckType().getCheckResultFormat(), searchParam.getTableName())); } } } catch (Exception e) { // 异常情况先通过 LOGGER.error("code check error, check content: {}, defaultDb: {}, checkType: {}", checkContent, defaultDb, getCheckType().name()); } return Result.buildSuccessResult(); } @Override public CodeCheckType getCheckType() { return CodeCheckType.TYPE_01; } } 如何自定义代码检查规则? 如果内置的代码检查规则不满足客户的使用场景,客户可以通过上传 jar 的方式自定义代码检查规则。 自定义代码检查规则使用 SPI 机制加载用户上传的自定义 jar,并在代码检测时调用 CodeCheck 方法,在资源关闭时调用 close 方法,用户需要将配置文件说明中的 jar 依赖自己的项目中。具体如下: ● 创建一个类实现接口 创建一个类实现接口 com.dtstack.assets.spi.codecheck.ICodeCheckClient 并实现 CodeCheck 和 close 方法,书写相关逻辑代码,如果校验通过需要将 CheckResult 对象中 success 设置为 true,失败时设置 success 字段为 false 并设置校验不通过的理由。 package com.dtstack.assets.spi.codecheck; import java.util.Map; public interface ICodeCheckClient { /** * 代码检查 * * @param checkContent 检查内容 * @param extMap 扩展配置 * @return 检查结果 */ CheckResult codeCheck(String checkContent, Map<String, Object> extMap); /** * 释放资源, 调用时需要关闭所使用的资源 */ void close(); } · 入参字段解释 – checkContent 为单条 SQL 信息 – extMap 会设置一些平台的属性,包含任务名称、任务类型等 · 出参字段解释 – success 为是否校验通过,必须设置 – checkResult 为校验结果,校验不通过时不能为空 package com.dtstack.demo; import com.dtstack.assets.spi.codecheck.CheckResult; import java.util.Map; public class CodeCheckImpl implements com.dtstack.assets.spi.codecheck.ICodeCheckClient{ @Override public CheckResult codeCheck(String checkContent, Map<String, Object> extMap) { // 代码检查相关逻辑 CheckResult checkResult = new CheckResult(); checkResult.setSuccess(false); checkResult.setCheckResult("校验不通过的理由"); return checkResult; } @Override public void close() { // 关闭相关资源 } } ● 在 resource 目录下创建 META-INF/services 目录 ● 在 META-INF/services 目录下创建文件 文件名称为 com.dtstack.assets.spi.codecheck.ICodeCheckClient ,文件内容为实现 ICodeCheckClient 接口类的权限定类名。 文件名称和内容示例: ● 打包当前工程并在数据资产页面注册代码校验规则 不符合条件的 jar 会给出提示。 如何加载自定义代码规则对应的 jar ? 我们会为上传的每个规则对应的 jar 初始化一个唯一的自定义 classloader,该 classloader 继承 URLClassLoader 并保证子类加载器优先加载。 在第一次调用时进行加载并缓存对应的 client。 在用户重新上传或者编辑规则后清除旧的 classloader 和加载的 client 并释放资源。 《数栈产品白皮书》:https://www.dtstack.com/resources/1004?src=szsm 《数据治理行业实践白皮书》下载地址:https://www.dtstack.com/resources/1001?src=szsm 想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:https://www.dtstack.com/?src=szkyzg 同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术qun」,交流最新开源技术信息,qun号码:30537511,项目地址:https://github.com/DTStack

优秀的个人博客,低调大师

Monibuca v4.6.5 发布 —— 开源 Go 语言流媒体服务

发布摘要 启动工程增加对流的发布订阅的单元测试和基准测试 修复发布和订阅并发创建流产生的panic 修复IdleTimeout无效问题 修复订阅者阻塞导致读写并发问题 preview插件修复https默认端口 gb28181插件PR合并 升级模块 升级后版本 engine 4.13.5 gb28181 4.3.6 hls 4.3.1 preview 4.1.2 record 4.3.7 详细说明 单元测试和基准测试 测试用例所在目录:github.com/langhuihui/monibuca工程下的test目录 推荐使用vscode打开工程,方便一键测试单个用例,也可以通过vscode侧边栏里的单元测试栏目管理。 TestPubAndSub funcTestPubAndSub(t*testing.T){ t.Cleanup(FreeEngine) UseEngine() t.Run("publish",func(t*testing.T){ t.Parallel() varpubUnitTestPublisher unitTestPlugin.Publish("test/001",&pub) }) t.Run("subscribe",func(t*testing.T){ t.Parallel() varsubUnitTestSubsciber sub.TB=t err:=unitTestPlugin.Subscribe("test/001",&sub) iferr!=nil{ t.Fatal(err) }else{ sub.PlayRaw() } }) } 该用例会启动一个发布者和一个订阅者,发布者将会写入假数据,订阅者读取后会校验数据是否正确。 BenchmarkPubAndSub funcBenchmarkPubAndSub(b*testing.B){ b.Cleanup(FreeEngine) UseEngine() fori:=0;i<10;i++{ i:=i gofunc(iint){ varpubUnitTestPublisher unitTestPlugin.Publish(fmt.Sprintf("testb/%d",i),&pub) }(i) gob.RunParallel(func(pb*testing.PB){ varsubUnitTestSubsciber sub.TB=b err:=unitTestPlugin.Subscribe(fmt.Sprintf("testb/%d",i),&sub) iferr!=nil{ //b.Fatal(err) }else{ sub.PlayRaw() } }) } time.Sleep(time.Second*10) } 该用例为基准测试,启动10个发布者,每个流会批量订阅,以测试并发性能以及稳定性。 TestSlowSubscriber funcTestSlowSubscriber(t*testing.T){ t.Cleanup(FreeEngine) UseEngine() varpubUnitTestPublisher unitTestPlugin.Publish("test/slow",&pub) varsuberSlowSubsciber unitTestPlugin.Subscribe("test/slow",&suber) suber.PlayRaw() } 这个用例会模拟一个订阅者被阻塞(sleep)后导致发布者写入的位置追上,此时engine通过标记这个写入点废弃来避免并发读写问题,废弃后订阅者如果被唤醒就会自动停止订阅。 通常出现这种情况是订阅者进行了某种耗时操作,比如写文件,或者网络阻塞等。 其他修复问题 并发创建流 修复如下: funcfindOrCreateStream(streamPathstring,waitTimeouttime.Duration)(s*Stream,createdbool){ p:=strings.Split(streamPath,"/") iflen(p)<2{ log.Warn(Red("StreamPathFormatError:"),streamPath) returnnil,false } actual,loaded:=Streams.LoadOrStore(streamPath,&Stream{ Path:streamPath, AppName:p[0], StreamName:strings.Join(p[1:],"/"), StartTime:time.Now(), +Logger:log.LocaleLogger.With(zap.String("stream",streamPath)), +timeout:time.NewTimer(waitTimeout), }) ifs:=actual.(*Stream);loaded{ s.Debug("StreamFound") returns,false }else{ -s.timeout=time.NewTimer(waitTimeout) s.Subscribers.Init() -s.Logger=log.LocaleLogger.With(zap.String("stream",streamPath)) -s.Info("created") s.actionChan.Init(1) +s.Info("created") gos.run() returns,true } } 原理:当并发调用findOrCreateStream函数时,前者尚未来得及对Logger赋值,后者就调用了s.Debug导致空指针错误。 修复读写并发问题 这个问题在前面的单元测试中已经提到,就是订阅者阻塞引起的。 订阅者阻塞后,读取点移动很慢或者不移动,导致写入点追上 由于RingBuffer是由链表结构实现,因此很容易将节点剥离主环 废弃后,这个订阅者将无法再读取主环内容,也将遭到抛弃 抛弃 https默认端口 默认https端口已经设置为8443,preview插件在选择WebTransport的时候跳转错了端口号。 https证书已经嵌入到程序里面,可以直接设置host文件127.0.0.1 local.monibuca.com访问https://local.monibuca.com:8443/preview/ gb28181 合并PR #95 本次PR主要修改了定时任务相关功能,包括: 定时删除超时设备 修改注册有效期配置默认值为3600s 设备状态变更处理 具体可以看代码变动

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册