普通视图

发现新文章,点击刷新页面。
昨天以前且炼时光

WSL开发系列-基础篇

作者 John Doe
2023年2月11日 22:54

本人使用win11+idea+docker+wsl2作为日常开发测试环境,
随着版本的迭代完善,加上本人丰富的踩坑经验,wsl已基本能满足我对linux单机使用的需求。
故重新整理wsl开发环境相关配置、优化、使用集成,形成本系列文章。
本文为WSL开发系列的开篇,也是目录,建议阅读此篇,再根据需求跳转。

WSL开发系列-gui篇(wslg)

作者 且炼时光
2023年2月11日 22:54

直到2022年,wslg的体验仍较差,难以用于日常开发,大部分情况下不建议使用

导航

0-1 为什么我不推荐使用wslg

  1. 当前wslg不成熟,bug较多,如idea频繁卡死(冻结)导致文件修改丢失、全屏偏移等
  2. 正经人谁用linux是为了gui?

0-2 wslg有哪些应用场景

以我浅薄的开发经历来说,只有一次,
就是使用wsl的chrome浏览器访问被kerberos保护的hadoop web界面。

虽然理论上windows的浏览器也可以做到,但是麻烦得多。
而在linux系统中,kerberos认证就是kinit一个指令的事情。

1 中文环境及输入法

这个教程比较多,而且写得都不一样,但大同小异,需要注意的是
输入法没有切换处理很可能是快捷键被windows系统的覆盖了,
需要手动调出来输入法的配置界面,修改快捷键
比方说fcix的是fcitx-config-gtk3命令
然后我的配置是这样的,就是shift键,保持和windows使用习惯统一

这里的教程可以参考:https://monkeywie.cn/2021/09/26/wsl2-gui-idea-config/
搜狗输入法参考:https://zhuanlan.zhihu.com/p/142206571
搜狗输入法配置命令:sogouIme-configtool
我的配置和里面的不一样, 也没有遇到idea切不出输入法的问题
如果有的话参考文章里的方法或者看:https://github.com/microsoft/wslg/issues/278

2 手动添加软件的快捷方式到开始菜单

cd ~/.local/share/applicationssudo cp *.desktop /usr/share/applications

参考链接:https://juejin.cn/post/6966630345915498526

3 wslg处理快捷方式无法以root用户运行应用

很多linux的软件默认不支持root用户启动,如chrome,会报错:

Running as root without --no-sandbox is not supported. See https://crbug.com/638180

这是报错原理:
wslg的应用通过windows快捷方式启动时,用的是wsl默认用户,
而我设置的默认用户是root,会导致闪退。
因为wslg我使用频率很低,故没必要特地去把默认用户改为普通用户。

这里介绍下几种处理方法

(0) 修改默认用户

使用范围:平常习惯使用sudo命令操作的
有效期:永久

Ubuntu-20.04 config --default-user 系统安装时创建的用户

(1) 修改linux桌面图标配置(原理:修改启动命令)

适用范围:可以在启动命令中添加特定选项规避问题的,如chrome可使用--no-sandbox
有效期:直到软件更新(图标刷新)

以下为例子

去 /usr/share/applications 目录对chrome的快捷方式进行编辑,修改其启动命令

vim /usr/share/applications/google-chrome.desktop

在其Exec列添加 --no-sandbox ,如下

Exec=/usr/bin/google-chrome-stable --no-sandbox  %U

(2) 修改windows-wslg桌面图标配置(原理:修改调用用户)

适用范围:所有
有效期:重启失效

有些软件(如firefox)就是不支持root用户运行,
这个时候需要修改其windows图标对应启动命令,指定用户启动

如下,linux的图标所在文件夹类似:C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Ubuntu-20.04
将快捷方式-属性-目标由“C:\Windows\System32\wslg.exe ~ -d Ubuntu-20.04 firefox”改为
“C:\Windows\System32\wslg.exe ~ -d Ubuntu-20.04 su 用户名 -c firefox”

linux图标
firefox属性

(3)直接shell启动

适用范围:所有
有效期:shell会话

su 普通用户google-chrome/firefox

4 在wslg使用chrome访问kerberos页面

wslg-chrome安装见:https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps#run-linux-gui-apps

  1. 配置kerberos
mkdir -p /etc/opt/chrome/policies/managed/cat << 'EOF' > /etc/opt/chrome/policies/managed/kerberos.json{ "AuthServerAllowlist": "*",  "AuthNegotiateDelegateAllowlist": "*" }EOF
  1. 启动
kinit -kt /home/admin02.service.keytab admin02/adp@HADOOP.COMgoogle-chrome --no-sandbox

其他

直接使用windows访问kerberos页面

参考 https://blog.csdn.net/sinat_20554629/article/details/105283518
在Windows上,必须使用Firefox + MIT Kerberos Windows客户端进行认证
不支持edge、chrome、ie等

firefox访问kerberos参考:
https://blog.csdn.net/IUNIQUE/article/details/108615090
https://www.cnblogs.com/kischn/p/7443343.html

具体操作流程参考如下:
1.下载并安装mit kerberos客户端
下载地址:https://web.mit.edu/kerberos/dist/
2.修改PATH
安装完了kerberos就自动的在 PATH 里面加上了自己的目录,但是在最后。
jdk也自带了kerberos工具,所以需要跳转PATH里kerberos的优先级在前面
3.将krb5.conf文件内容复制到krb5.ini
完整默认路径:C:\ProgramData\MIT\Kerberos5\krb5.ini
4.kinit登录
5.修改firefox配置
1. 输入 about:config
2. 修改配置项 network.negotiate-auth.trusted-uris 的值为: master01,worker01
3. 修改配置项 network.auth.use-sspi 的值为: false
4. 重启firefox
6.使用firefox打开kerberos页面

注意:机器重启会导致kinit信息失效

gitlab-ci-k8s-runner部署及缓存配置说明

作者 且炼时光
2023年1月31日 23:00

因gitlab-ci的k8s-runner会将job里的每个stage都交由单独的pod来执行,导致默认的本地缓存无法使用。
本文记录了基于k8s pv的gitlab-ci的缓存配置方案,无需使用S3分布式存储。
并记录了gitlab-ci-k8s-runner相关的配置、部署步骤等。

gitlab-ci-k8s-runner部署及缓存配置说明

一 gitlab-ci-cache机制说明

参考:https://blog.csdn.net/xichenguan/article/details/101439395

Gitlab cache 机制可以大大加快 CI/CD Job 的执行速度。基础知识可以参看 Gitlab Cache
下面直接总结在 Kubernetes 环境中的三种 Cache 的解决方案。

1. Distributed runners caching

gitlab runner job执行前从分布式存储中检查下载解压 cache 文件,job执行后,压缩上传 cache 文件到分布式存储。这是 gitlab 提供的通用的正宗的方法,在非 Kubernetes 环境中也可以使用;

2. 给 Job Executor Pod 挂载同一个 volume

gitlab runner 提供了本地存储 cache 的方式,如果远程存储没有配置,gitlab runner 照样会压缩 cache 文件,然后按照目录规则存储到指定的目录。这种方式的原理是将此目录配置为 Kubernetes Volume,每个 Job 执行时都挂载此 Volume ,这样就相当于所有的 Job 有了一个集中式的存储。可以参考 使用GitLab CI在Kubernetes服务上运行GitLab Runner并执行Pipeline 尝试配置。

3. 不使用缓存,在 Kubernetes 集群中安装各类仓库的私服

Gitlab CI/CI Job 执行时,配置为使用这些私服,速度也很快。

注意:方式1一般指S3存储,建议使用方式2

二 准备缓存pv、pvc

1.配置runner nfs缓存目录

export CACHE_DIR=/home/runner-cachemkdir -p $CACHE_DIRchmod -R 777 $CACHE_DIRecho "$CACHE_DIR *(rw,sync,no_root_squash,all_squash,no_subtree_check,anonuid=0,anongid=0)" >> /etc/exportsexportfs -ashowmount -e localhost

2.创建pv、pvc

kubectl -n=命名空间 apply -f gitlab-runner-pv-pvc.yaml

3. 创建imagePullSecret

参考:https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account

kubectl -n=命名空间 create secret docker-registry myregistrykey --docker-server=DUMMY_SERVER \        --docker-username=DUMMY_USERNAME --docker-password=DUMMY_DOCKER_PASSWORD kubectl -n=命名空间 get secret myregistrykeykubectl -n=命名空间 get secret myregistrykey --output=json

4. 可选:将gitlab-runner、gitlab-runner-helper镜像上传到私有仓库

gitlab-runner镜像

docker tag registry.gitlab.com/gitlab-org/gitlab-runner:alpine-v15.8.0 私有仓库/gitlab-runner:alpine-v15.8.0docker push 私有仓库/gitlab-runner:alpine-v15.8.0

gitlab-runner-helper镜像

docker tag registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper:x86_64-12335144 私有仓库/gitlab-runner-helper:x86_64-12335144docker push 私有仓库/gitlab-runner-helper:x86_64-12335144

三 根据官方helm生成k8s-runner部署文件

参考:https://docs.gitlab.com/runner/install/kubernetes.html
默认values.yaml文件:https://gitlab.com/gitlab-org/charts/gitlab-runner/blob/main/values.yaml

helm repo add gitlab https://charts.gitlab.iohelm repo update gitlabhelm install --dry-run --debug --namespace 命名空间 \gitlab-runner -f values.yaml gitlab/gitlab-runner > gitlab-runner-all.yamlkubectl -n=命名空间 apply -f gitlab-runner-all.yaml

四 附:docker-runner部署

运行

docker run -d --name gitlab-runner --restart always \  -v /home/gitlab-runner/config:/etc/gitlab-runner \  -v /var/run/docker.sock:/var/run/docker.sock \  gitlab/gitlab-runner:latest

注册

docker run --rm -it -v /home/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register

重启

docker restart gitlab-runnerdocker logs -f gitlab-runner

修改配置

在gitlab修改配置runner,支持运行未标记的作业

五 value.yaml和pv-pvc文件参考

gitlab-runner-pv-pvc.yaml

apiVersion: v1kind: PersistentVolumemetadata:  name: gitlab-runner-cache-pvspec:  storageClassName: gitlab-runner  capacity:    storage: 100Gi  accessModes:    - ReadWriteMany  nfs:    server: $NFS_SERVER    path: "$NFS_PATH"---apiVersion: v1kind: PersistentVolumeClaimmetadata:  name: gitlab-runner-cache-pvcspec:  accessModes:    - ReadWriteMany  storageClassName: gitlab-runner  resources:    requests:      storage: 100Gi

gitlab-k8s-runner-helm的value.yaml文件配置

参考:

  1. 默认values.yaml文件:https://gitlab.com/gitlab-org/charts/gitlab-runner/blob/main/values.yaml
  2. https://docs.gitlab.com/runner/executors/kubernetes.html#overwriting-container-resources
  3. https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnerskubernetes-section
image:  registry: "自行填写"  image: "自行填写"  tag: "自行填写"imagePullPolicy: IfNotPresentimagePullSecrets:  - name: "自行填写"gitlabUrl: "自行填写"runnerRegistrationToken: "自行填写"# runnerToken: ""# unregisterRunners: trueterminationGracePeriodSeconds: 3600# certsSecretName:concurrent: 10checkInterval: 30# logLevel:# logFormat:# sentryDsn:preEntrypointScript: |  echo "hello"sessionServer:  enabled: false  # annotations: {}  # timeout: 1800  # internalPort: 8093  # externalPort: 9000  # publicIP: ""  # loadBalancerSourceRanges:  #   - 1.2.3.4/32## For RBAC support:rbac:  create: true  rules: []  # - resources: ["configmaps", "pods", "pods/attach", "secrets", "services"]  #   verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]  # - apiGroups: [""]  #   resources: ["pods/exec"]  #   verbs: ["create", "patch", "delete"]  clusterWideAccess: false  # serviceAccountName: default  # serviceAccountAnnotations: {}  podSecurityPolicy:    enabled: false    resourceNames:      - gitlab-runner  ## Specify one or more imagePullSecrets used for pulling the runner image  ##  ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account  ##  imagePullSecrets: []metrics:  enabled: false  portName: metrics  port: 9252  serviceMonitor:    enabled: false    ## labels: {}    # interval: ""    # scheme: "http"    # tlsConfig: {}    # path: "/metrics"    # metricRelabelings: []    ## relabelings: []service:  enabled: false  # labels: {}  # annotations: {}  # clusterIP: ""  # externalIPs: []  # loadBalancerIP: ""  # loadBalancerSourceRanges: []  type: ClusterIP    # metrics:  # nodePort: ""  # additionalPorts: []runners:  # runner configuration, where the multi line strings is evaluated as  # template so you can specify helm values inside of it.  #  # tpl: https://helm.sh/docs/howto/charts_tips_and_tricks/#using-the-tpl-function  # runner configuration: https://docs.gitlab.com/runner/configuration/advanced-configuration.html  # 见:1. https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnerskubernetes-section  #  2. https://docs.gitlab.com/runner/executors/kubernetes.html#overwriting-container-resources  config: |    [[runners]]      cache_dir = "/cache"      [runners.kubernetes]        namespace = "自行填写"        image = "自行填写"        privileged = true        image_pull_secrets = ["自行填写"]        image_pull_policy = "if-not-present"        helper_image = "自行填写"        helper_cpu_limit = "1000m"        helper_memory_limit = "2048Mi"        helper_cpu_requests = "200m"        helper_memory_requests = "512Mi"        service_cpu_limit = "1000m"        service_memory_limit = "2048Mi"        service_cpu_requests = "200m"        service_memory_requests = "512Mi"        cpu_limit = "1000m"        cpu_limit_overwrite_max_allowed = "5000m"        memory_limit = "2048Mi"        memory_limit_overwrite_max_allowed = "10240Mi"        cpu_requests = "200m"        cpu_requests_overwrite_max_allowed = "5000m"        memory_requests = "512Mi"        memory_requests_overwrite_max_allowed = "10240Mi"        [[runners.kubernetes.volumes.host_path]]          name = "docker"          mount_path = "/var/run/docker.sock"          read_only = true          host_path = "/var/run/docker.sock"        [[runners.kubernetes.volumes.pvc]]           name = "gitlab-runner-cache-pvc"           mount_path = "/cache"securityContext:  allowPrivilegeEscalation: false  readOnlyRootFilesystem: false  runAsNonRoot: true  privileged: false  capabilities:    drop: ["ALL"]podSecurityContext:  runAsUser: 100  # runAsGroup: 65533  fsGroup: 65533  # supplementalGroups: [65533]  ## Note: values for the ubuntu image:  # runAsUser: 999  # fsGroup: 999## Configure resource requests and limits## ref: http://kubernetes.io/docs/user-guide/compute-resources/##resources:   limits:     memory: 2048Mi     cpu: 1000m   requests:     memory: 512Mi     cpu: 200maffinity: {}nodeSelector: {}tolerations: []# envVars:#   - name: RUNNER_EXECUTOR#     value: kuberneteshostAliases: []  # Example:  # - ip: "127.0.0.1"  #   hostnames:  #   - "foo.local"  #   - "bar.local"  # - ip: "10.1.2.3"  #   hostnames:  #   - "foo.remote"#   - "bar.remote"podAnnotations: {}  # Example:# iam.amazonaws.com/role: <my_role_arn>podLabels: {}  # Example:  # owner.team: <my_cool_team>priorityClassName: ""secrets: []  # Example:  # - name: my-secret  # - name: myOtherSecret  #   items:  #     - key: key_one#       path: path_oneconfigMaps: {}volumeMounts:  - name: cache    mountPath: /cachevolumes:  - name: cache    persistentVolumeClaim:      claimName: gitlab-runner-cache-pvc

我的服务器系列:tailscale使用自定义derper服务器(docker部署)

作者 且炼时光
2022年4月16日 22:54

使用docker部署tailscale私有中继服务器,并使用nginx四层代理与原有服务共用443端口,最后配置使用并检测。
derper-docker部署及使用较麻烦,本文分享踩坑记录及经验,建议阅读。

一 设计及参考

设计

  1. 使用DockerHub上面唯一主流的derper镜像进行部署,保证可靠性
  2. 使用nginx四层代理转发443端口请求到derper容器
  3. 在tailscale上面配置使用derper服务器
  4. 测试derper的连通

参考

推荐阅读:
官方说明(https://tailscale.com/kb/1118/custom-derp-servers/)
TAILSCALE 的一些使用心得(https://leitalk.com/12245)
Tailscale 基础教程:部署私有 DERP 中继服务器(https://icloudnative.io/posts/custom-derp-servers)

二 部署derper容器

参考:https://hub.docker.com/r/fredliang/derper
下面是我个人的配置
注意:

  1. ssl证书
    ssl证书可外部挂载或由容器自动申请并维护证书更新(基于LetsEncrypt)
    因为derper使用的ssl证书有格式和命名要求,挂载使用很不优雅,故放弃该方案
    而自动申请需要使用443端口,因为我443端口已经使用了,所以需要用nginx stream反向代理的形式做443端口4层转发。
    后文会进行详细说明。
  2. 3478端口不能修改,因为走udp所以也不建议转发。
  3. 如果使用DERP_VERIFY_CLIENTS则需要挂载tailscaled.sock,使容器能访问到外部机器derper进程。
mkdir -p /data/derper/certsdocker rm -f derperdocker run -d \-p 3443:443 \-p 3478:3478/udp \--name derper \--restart=always \-v /data/derper/certs:/app/certs \-v /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock \-e DERP_ADDR=":443" \-e DERP_VERIFY_CLIENTS=true \-e DERP_DOMAIN="derper.linshenkx.cn" \fredliang/derperdocker logs -f derper

derper服务器

三 nginx代理配置

虽然有些人说derper运行一段时间就会崩溃(Derper TLS handshake error: remote error: tls: internal error),
但我没有遇到过,按照官方issueTAILSCALE 的一些使用心得里的说法,可能和墙/备案有关。

顺带一提,如腾讯云这样的国内云服务器提供商,会审查 TLS handshake 里的 SNI 信息, 如果发现 SNI 域名未备案,会阻断 TLS 握手。 所以,我曾经也尝试过用一个境外服务器的域名,然后指向到境内服务器 IP 的形式尝试绕过备案, 然而短暂的用了几分钟后,就遇到了 tls handshake reset 的问题。 目前看来,只要你想用境内服务器,那么备案就是绕不过的问题。
Ps. 如果你有备案域名,那么可以用 nginx stream 反向代理的形式做 443 端口 4 层转发。 nginx stream 可以在四层探测 SNI 信息,然后分发到不同的后端,这样你 derper 的 443 和其他域名的 443 就可以共存在同一个服务器上了。

这里主要知识点是:

  1. TLS handshake 里的 SNI 信息
  2. nginx四层负载均衡

具体配置参考我的另外一篇文章:TODO

四 tailscale配置

Access Contros配置内容参考如下:
主要是添加了derpMap,其他都保持默认。
如果有多个derper服务器,建议配置为多个region而非node。
因为延迟的比较是以region为单位的,会方便测试。

一开始不确定derper是否运行正常的时候,建议先把OmitDefaultRegions设置为true,关闭默认的region。

另外,修改Access Contros后,需要重启tailscale服务才能生效!

// Example/default ACLs for unrestricted connections.{  // Declare static groups of users beyond those in the identity service.  "groups": {    "group:example": [ "user1@example.com", "user2@example.com" ],  },  // Declare convenient hostname aliases to use in place of IP addresses.  "hosts": {    "example-host-1": "100.100.100.100",  },  // Access control lists.  "acls": [    // Match absolutely everything. Comment out this section if you want    // to define specific ACL restrictions.    { "action": "accept", "users": ["*"], "ports": ["*:*"] },  ]  ,  "derpMap": {    "OmitDefaultRegions": false    ,    "Regions": {      "900": {      "RegionID": 900,      "RegionCode": "lian",      "RegionName": "LIAN",      "Nodes": [{          "Name": "tx",          "RegionID": 900,          "HostName": "derper.linshenkx.cn",          "DERPPort": 443      }     ]    }    //   ,    //   "901": {    //   "RegionID": 901,    //   "RegionCode": "lian2",    //   "RegionName": "LIAN2",    //   "Nodes": [{    //       "Name": "uc",    //       "RegionID": 901,    //       "HostName": "derper2.linshenkx.cn",    //       "DERPPort": 443    //   }    //  ]    // }    }  }}

五 测试使用derper

相关命令

# 显示集群状态tailscale status# 显示网络状态tailscale netchecktailscale ping 节点

如下图,自定义的derper比默认的延迟要低不上。
(不过只有在极端情况下流量才会走derper,通常derper只要连得上就行,所以延迟影响不大)
tailscale netcheck

需要注意的是,这里显示一切正常,不代表derper就是在正常工作了。
只是说能访问到 https://derper.linshenkx.cn 而已。

关键还是要看ping。
tailscale ping
如图,代表了几种情况:

  1. tx.linshenkx.cn
    先通过DERP(sfo)连接,然后打洞成功,进化为ip:端口直连
  2. uc.linshenkx.cn
    识别到是本机
  3. lian.linshenkx.cn
    尝试通过DERP(lian)连接,但失败(因为对方tailscale服务异常)
  4. nas.linshenkx.cn
    先通过DERP(lian)连接,然后打洞成功,进化为ip:端口直连

derper日志类似如下
docker logs -f derper

ubuntu获取离线安装包

作者 且炼时光
2022年4月9日 11:55

工作经常会遇到需要离线安装软件的情况,特此记录下来,避免每次都得去翻笔记。

一 构造运行环境

1 使用docker提供目标操作系统

在本地创建data目录并挂载到容器里,方便将生成的依赖取出。

  1. centos7
mkdir -p /home/lin/ubuntu22/datadocker rm -f ubuntu22docker run -d  --name ubuntu22 -v /home/lin/ubuntu22/data:/data ubuntu:22.04 tail -f /dev/nulldocker exec -it ubuntu22 /bin/bash

2 更新yum镜像仓库

参考阿里的开源镜像站:https://developer.aliyun.com/mirror/

cp -a /etc/apt/sources.list /etc/apt/sources.list.bak \    && sed -i "s@http://.*archive.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list \    && sed -i "s@http://.*security.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list \    && apt-get update

二 下载依赖包

以nfs-common为例

apt-get cleanmkdir /data/nfsapt-get install --reinstall -d -y nfs-commonmv /var/cache/apt/archives/*.deb /data/nfs/

三 安装

将生成的文件夹拷贝到目标集群上

dpkg -i *.deb

基于hdfs的ftp服务器的设计与实现

作者 且炼时光
2022年1月17日 23:05

本文主要记录hdfs-ftp-server的设计思路、实现过程,使用的话直接看github项目文档即可。
项目地址:https://github.com/linshenkx/hdfs-ftp-server

第一版

hdfs-ftp-server这个项目我在20年的时候就开源过一版了,先做一下前提介绍。

1 需求

因为我们大数据平台是容器化的,一些简单的操作也需要进入容器里面才能执行,而且传递文件也很繁琐。
所以那时候的主要需求就是实现功能,即通过ftp的方式实现对hdfs文件系统的操作,方便日常操作。

2 思路

那时候主要是参考github上一些老一点的项目进行改造升级,以适配高可用、kerberos认证连接。
然后再进行易用性改造,更适合生产环境使用。

核心思路是对外作为ftp服务器,内部使用hdfs实现接口功能即可,很简单的功能。

3 存在问题

那时候用的hadoop是官方的2.9.2,后面hadoop升级到3.3.1了,
而且有时候还得对接cdh的hadoop,这个时候这个工程就不能直接拿来用了。

这种时候常规解决办法就是修改一下依赖,重新编译。

但是我觉得太麻烦了,这样也不利于代码的管理。
所以就一直想着要把这个工程模块化,核心工程独立且不常变,其他的作为模块工程对接各个版本的hadoop客户端。

第二版

针对第一版存在的问题,第二版主要是对项目进行模块化改造

技术调研及选型

最开始我目标是很明确的,就是用蚂蚁金服的ark框架来实现类隔离,
毕竟不同大版本/发行版本的hdfs依赖多少会有类冲突,直接用是肯定不放心的。

ark我之前就一直有在留意,也跑过demo,觉得还是可以寄予厚望的。
事实上这个工程重构所用的时间一大半都花在ark上。
本来是想把各个实现模块作为ark的插件的,发现ark的插件又不支持动态插拔,其核心是类隔离而不是模块化。
那就把每个模块作为service,来实现动态引用,这也是可以的,也确实改好代码打包好了。
但最终运行的时候还是有bug,类似于:https://github.com/sofastack/sofa-ark/issues/421。

终于还是折腾不下去,放弃ark了,开源支持太差了,我水平有限,玩不动。

不用ark,osgi又太重了,没必要,那就还是老老实实用java的spi吧。
类似于jdbc的用法,添加对应jar包,指定类名进行加载。

但spi并不能实现类隔离,所以就预先打包好各个jar包,运行时再根据对接hadoop版本进行加载。

即每个模块形成一个fatjar,如cdh632.jar,official331.jar。
在对接cdh6.3.2的时候将cdh632.jar添加到类路径下即可,如果是对接官方3.3.1则添加official331.jar。

这里还有一个问题,要不要把hadoop的依赖包也一并打包呢?
这个倒没纠结太久,还是打包了。缺点是体积大很多,优点是摆脱依赖。
你只需要给我hadoop的连接配置文件就行了,而不需要整个hadoop客户端环境。
至于包大点就大点,不差那点流量、空间。

为了简化、统一子模块的开发,我又把gradle任务统一定义在父工程的build.gradle里面。
让子模块更加的简单易懂。

成果总结

https://github.com/linshenkx/hdfs-ftp-server

应该说还是比较满意的。

虽然就技术来说很简单,毕竟别人十年前就做过的东西,
但还是花了很多时间、心思在上面折腾,把这个小东西做得好用一些。
在这个过程也算有点收获吧。

❌
❌