分类: 默认

  • 云上部署的便利性和方案

    云上部署的便利性和方案

    本文首发于:https://developer.aliyun.com/article/863742 修改于发布于本博客

    每年双十一的时候,由于云厂商对于新用户的推广和补贴用户,总会有一些非技术的同事买云主机或者其他类似服务,买了以后也没啥诉求,就想看能不能搭个博客或者小网站自己玩玩。除了个人用户以外,也有一些小公司可能也有类似诉求,需要一个简单的项目管理或者其他企业软件,一般的诉求都是免费或者花钱少,简单,后期别出问题。

    我们就用wordpress举例,考虑最简单的wordpress也需要一个PHP环境,一个数据库,如果还需要https,那还需要一个nginx或者caddy。

    手动安装

    手动其实比较麻烦,php环境、数据库和caddy可以使用apt/yum安装,再从wordpress官网下载最新版本,解压使用。数据库需要手动改下密码,然后wordpress配置连接。这么一套,10分钟肯定跑不掉。

    而且这还是最基本的,还需要考虑端口的开放,应用的安全配置等等。

    Docker-compose方案

    docker是最容易想到的方案。

    一般来说为了方便我都会帮忙用docker-compose的方式部署一下,几行命令就能搞定,配置文件如下:

    version: "3.9"
        
    services:
      db:
        image: mysql:5.7
        volumes:
          - db_data:/var/lib/mysql
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: somewordpress
          MYSQL_DATABASE: wordpress
          MYSQL_USER: wordpress
          MYSQL_PASSWORD: wordpress
        
      wordpress:
        depends_on:
          - db
        image: wordpress:latest
        volumes:
          - wordpress_data:/var/www/html
        ports:
          
  • 谈API网关

    文章首发于阿里云开发者社区:https://developer.aliyun.com/article/862205

    API 网关是位于客户端与后端服务集之间的管理工具/平台。简单来说大致相当于一个反向代理,可以调用并返回结果。

    价值

    API网关并不是必须的,如果处于起步阶段的项目,单体应用还是最直接的,一层Controller就可以解决问题,这个阶段引入过多的复杂性其实没有太大必要。

    但是对于大型应用,特别是微服务化的场景下,API网关可以带来很多价值:

    聚合和解耦

    当用户需要同时访问多个接口的时候,网关可以聚合结果,节约流量。

    网关由于路由规则等比较灵活,可以比较容易的切换网关后的路由,对于一些升级、迁移场景,可以降低影响。特别是业务迭代早期,服务之前的边界和模型不稳定,迭代是极为频繁的。

    非业务功能

    在实际的应用场景中,有很多功能是必要的,但是它不是业务功能,比如限流、降级、熔断等。网关可以用较低代价去实现通用能力,并提供一些通用的模块,比如认证接入等。

    管理

    网关统一了所有对外暴露的接口,也就有条件提供一个统一的管理工具,这样可以给API更统一的管理模型,统一生命周期。

    评价

    评价一款API网关主要看性能和功能,另外个人还觉得和已有生态的结合也是一个考虑点。如果是自建/自部署,还要考虑开源社区的活跃程度和二次开发的复杂度。

    性能测试网上有很多,一般都是使用几台压测机进行施压,观察平均响应时间、吞吐量和响应时间分布。这样测试一般后端都是空接口(没有业务逻辑),无法模拟真实情况下的连接波动等的影响。

    功能的话,大部分流行的API网关功能都是完备的,只要是叫得上名字的,功能都大同小异,这种情况下可以重点关注下监控系统的集成。

    选型

    API网关由于通用性比较强,相对来说选型也比较多。

    常见的开源选择有Kong、Ambassador、Traefik、Tyk等。

    部分开源网关也有商业版/商业支持,如果目前已经上云了,那其实完全可以使用云厂商的网关,差不多都是按流量+次数收费,也有买断式的专享实例,这种按照时长+流量收费。

    对于云厂商来说,API网关属于最基本的功能了,都有提供,但云厂商提供的API网关存在厂商锁定问题,后期切换不容易。

  • 自定义Jellyfin插件

    最近把多媒体管理软件从Plex切换到Jellyfin了,之前用的ttm搜刮器做的整理,最近由于Nas没有放在住的房屋,远程管理比较麻烦,所以又把目光放回Jellyfin的插件上。

    由于动漫都是走Sonarr下载的,把rename打开以后识别上就没啥大问题了。官方自带了themoviedb的插件,但是一是不支持代理,二是包含了很多YouTube的信息,这个确实不必要。所以自己参考写了一个插件,主要是支持Proxy方便访问themoviedb,二是移除了一些不需要的信息。

    插件编写

    插件的编写使用C#,主要就是实现对应的接口,主要是IRemoteMetadataProvider和IRemoteImageProvider。一个负责源数据,一个负责图片。

    我一般是用TV和Movie两种,其中TV的集数识别可以依赖Jellyfin,当然如果有需要也可以自己实现从文件名分析。

    插件测试

    插件的测试自然可以用单元测试,但是由于一般来说插件主要做的是把信息转为Jellfyin的对象,没有太多复杂逻辑。直接打包放到Jellfyin中使用就行了。

    在本地为了方便,我一般用docker-compose来启动。

    version: "3"
    
    services:
      jellyfin:
        image: jellyfin/jellyfin:latest
        volumes:
          - config:/config:z
          - ./videos:/media/videos
          - ./Jellyfin.Plugin.HappyMovie/bin/Debug/net5.0/Jellyfin.Plugin.HappyMovie.dll:/config/plugins/HappyMovie/Jellyfin.Plugin.HappyMovie.dll:ro
          - ~/.nuget/packages/yove.proxy/1.1.1/lib/netstandard2.0/Yove.Proxy.dll:/config/plugins/HappyMovie/Yove.Proxy.dll:ro
        ports:
          - 127.0.0.1:8896:8096
    
    volumes:
      config:

    dll文件路径根据自己的项目实际情况修改即可。这里也要包括外部依赖。比如我这里使用了代理配置,所以依赖了YoveProxy库。

    插件发布安装

    插件直接分发DLL即可完成安装。为了更好的方便普通用户使用,也可以提供一个manifest.json文件。

    这个文件的具体格式可以参考:https://raw.githubusercontent.com/htynkn/HappyMovie/master/manifest.json

    也有现成的python脚本可以生成。最关键是把DLL文件打包到zip中。…

  • 交叉编译给铁威马Nas添加wget

    铁威马Nas自带的系统不知道魔改的啥,很多基本工具都没有,比如wget。有时候需要从外边安装点啥,特别是下载脚本特别难。

    铁威马Nas就分两个架构的,x86和arm v8。我手上的都是x86的,官方提供了编译工具链,但是我自己的经验来看,目前还没有遇到不兼容的地方,直接用公开工具就行了。比如rust的x86工具链,或者cross的docker image也行。

    这里以wget为例,使用docker image来。

    首先下载源代码https://ftp.gnu.org/gnu/wget/wget-1.21.1.tar.gz,解压后执行docker命令进入容器。

    docker run -it -v $(pwd):/data rustembedded/cross:x86_64-unknown-linux-gnu-0.2.1 bash

    wget的编译方法看文档就行了,先configure,再make,然后我们也不用install,直接拷贝到Nas的/bin目录即可。

    ./configure --prefix=/usr      \
                --sysconfdir=/etc  \
                --with-ssl=openssl
    make
  • 云原生与Apache Dubbo 3.0

    如果需要下载,可以访问:https://089u.com/f/631225-496536778-45eb62(访问密码:7269)…

  • Switch Lan Play Openwrt版本常见问题排查

    如果需要在自己的Openwrt上安装lanplay插件,可以直接从:https://htynkn.github.io/openwrt-switch-lan-play/openwrt/ 下载对应的包。总共有两个ipk文件。

    常见问题排查

    • 确认自己下载的插件是否和自己硬件架构一致,不同的包是没法使用的。
    • 确认自己是否为标准Openwrt,版本是否为19.07.7?
    • 右上角是否有未提交提醒,如果有请先提交
  • 为Katacoda课程添加自动化测试

    Katacoda是一个很方便做课程的平台,提供免费的机器资源,丰富的环境和UI界面支持。

    Katacoda的课程是由配置+markdown+其他资源组成的,课程写好以后提交到Github就可以自动刷新。一般来说课程内容比较直接,一般写好以后试用一下就可以了,但是结合cypress工具我们也可以做一些简单的自动化测试。

    首先在目录创建文件夹.cypress,然后创建一个以_spec.js结尾的文件,在文件中编写测试接口。另外为了方便起见Katacoda额外提供了一些辅助功能,比如cy.startScenario()可以直接启动课程。

    这里是dubbo-admin的测试例子

    describe("Valid env and layout", () ={
      before(() ={
        cy.startScenario();
      });
    
      it('finds launch command"', () ={
        cy.contains(" launch.sh");
      });
    
      it("start k8s", () ={
        cy.terminalType("launch.sh");
    
        cy.terminalShouldContain("Kubernetes started");
      });
    });

  • Spring Native的使用

    Spring Native的使用

    Spring Native本质上其实是依赖于GraalVM的native image功能,所以要先安装相关依赖。

    安装graalvm

    MacOS的安装依赖brew,官方有一个tap。

    brew install --cask graalvm/tap/graalvm-ce-lts-java11

    安装以后使用gu工具安装native-image工具

    gu install native-image

    SpringNative构建

    首先进行的是AOT插件,插件会根据上下文进行一些优化,主要是为了增强native image的兼容性。

    其次会进行jar包构建,构建后的jar包也是可以在JVM环境下正常运行。

    最后就是build-image这一步,其实启用native与否的关键主要在buildpacks上。首先会自动探测需要应用的buildpacks。如果系统变量BP_NATIVE_IMAGE是true的话就会激活paketo-buildpacks/native-image

    这个插件的native目录包含了对应的GO文件,会调用native-image进行生成操作。生成后会放入image中。

    构建本身还是比较快的。

    出错情况

    最常见的出错就是native-image没有安装或者没有使用graalvm,一般提示native-image找不到。

    目前spring-native要求GraalVM 21.0.0,版本如果低了可能有部分参数不支持,比InlineBeforeAnalysis等。

    可以通过BP_NATIVE_IMAGE_BUILD_ARGUMENTS指定一些特殊参数,常见的如下:

    • –verbose
    • -H:+PrintAnalysisCallTree
    • -H:+TraceClassInitialization
    • -H:+ReportExceptionStackTraces
    • –enable-all-security-services
  • 通过Spring Native构建本地镜像

    Spring Native目前已经在start.spring.io开放使用了。GraalVM在之前已经支持了本地镜像的构建,即不要求JVM安装(不是简单的集成JVM,还有AOT等特性),只生成单一分发文件。现在Spring也可以使用快速使用这个特性了,命令行使用

    mvn spring-boot:build-image

    这个特性比较适合以下场景:

    • Serverless
    • 微服务
    • 分发更高性能和容量的镜像

    参考

    https://www.graalvm.org/reference-manual/native-image/

    https://spring.io/blog/2021/03/11/announcing-spring-native-beta

  • 集成测试的测试覆盖率统计

    单元测试的覆盖率一般都很好处理,直接使用对应的jacoco插件即可。但是一个项目不单单只有单元测试,还有集成测试等其他类型的测试。对于这些测试类型,测试覆盖率的统计还需要稍微处理下。

    首先集成测试是在先将测试工程打包成jar包再封装到docker镜像中,考虑到操作性和便利性,肯定要挂在一部分主机目录到镜像中。具体的统计使用jacoco的agent模式,参数上只配置输出文件,其他都采用默认值。

    首先是下载jacoco的agent和cli工具到jacoco目录中

    mkdir jacoco && wget https://repo1.maven.org/maven2/org/jacoco/org.jacoco.agent/0.8.6/org.jacoco.agent-0.8.6-runtime.jar -O jacoco/jacoco.jar && wget https://repo1.maven.org/maven2/org/jacoco/org.jacoco.cli/0.8.6/org.jacoco.cli-0.8.6-nodeps.jar -O jacoco/jacoco-cli.jar

    docker镜像启动时挂在目录到/jacoco目录,并在JAVA_OPTS参数中新增

    -javaagent:/jacoco/jacoco.jar=destfile=/jacoco/jacoco.exec

    这样就会在jacoco目录生成jacoco.exec文件了。

    第二部就是把exec文件转为报告,一般是xml格式的,这一步使用jacoco-cli即可。

    java -jar jacoco/jacoco-cli.jar report jacoco/jacoco.exec --classfiles dubbo-admin-server/target/classes/ --sourcefiles dubbo-admin-server/src --xml jacoco/jacoco.xml

    具体目录按照需要调整,源代码不是必选项。

    最后就是计算变更等后续处理了,由于使用的是codecov平台,这里使用flag区别下集成测试和单元测试就行了。

    效果如图: