Golang高级软件工程师 - 基础服务职位讨论
Golang高级软件工程师 - 基础服务职位讨论 IONOS凭借其商业应用,是欧洲领先的主机和云应用提供商之一。我们凭借先进的技术,每天赢得来自许多不同国家超过800万客户的信赖。
您的职责
IONOS内部服务团队正在寻找一位积极主动且经验丰富的软件工程师。 该团队专注于开发和维护“基础服务”,这些是内部服务,与多个(甚至所有)PaaS产品相关,例如配额管理、功能标志、标签、客户支持工具等。该团队是全新的,其任务和路线图尚未完全确立。我们的团队负责其服务的整个生命周期:我们构建它,我们交付它,我们运行它。 我们正在寻找一位加入我们团队并与我们合作提供最佳产品的人选。此职位向工程经理:内部服务汇报。
- 使用Go和其他语言进行编程
- 与一个敏捷且积极主动的同行团队协作
- 在动态的云环境中解决有趣的问题
- 支持分布式系统的运维和管理
- 持续改进我们的构建、测试和部署自动化
- 持续提高我们服务的质量和弹性
我们看重
- 开发、测试和部署精心设计代码的经验,最好是使用Go语言
- 对设计和架构讨论做出建设性贡献
- 在云环境和分布式系统方面的工作经验
- 具备Kubernetes容器编排和Helm charts的经验
- 具备生产环境运维和故障排除的经验
- 具备构建Kubernetes operators、controllers和CRDs的经验将是一个加分项
- 同样,具备Kafka经验将是有益的
更多关于Golang高级软件工程师 - 基础服务职位讨论的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你好 Pawel, 你考虑兼职吗?(约每周20小时)
此致, Przemysław
更多关于Golang高级软件工程师 - 基础服务职位讨论的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你好,Paweł,
抱歉,我之前没注意到关于德国居留的信息,这让我不符合条件……我目前在波兰,根据你的名字,这地方对你来说似乎很熟悉 🙂
此致, Przemysław
你好,普热梅斯瓦夫,
原则上兼职工作是可能的,但这需要在面试时讨论。我建议你直接申请这个职位。如果你的简历得到积极评价,我们会与你联系,届时可以澄清这些细节。请注意,根据社会保障法,该职位要求在德国有永久居留权。
此致, 帕维乌
这是一个非常典型的Go高级工程师职位,专注于云原生和基础服务领域。从职责和要求来看,这个岗位的核心是使用Go构建和维护高可用、分布式的内部平台服务。
职位描述中提到的“配额管理”、“功能标志”、“标签”等,在Go生态中通常通过设计良好的API、Operator和控制器来实现。以下是一个高度简化的、概念性的“功能标志”服务示例,它展示了这类基础服务可能涉及的技术模式:
// 示例:一个使用Go构建的、基于Kubernetes CRD的功能标志(Feature Flag)控制器核心部分
// 这展示了如何利用client-go和operator-sdk等框架来构建内部平台服务
package main
import (
"context"
"fmt"
"time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
// 定义自定义资源(CRD) - FeatureFlag
type FeatureFlag struct {
v1.TypeMeta `json:",inline"`
v1.ObjectMeta `json:"metadata,omitempty"`
Spec FeatureFlagSpec `json:"spec,omitempty"`
Status FeatureFlagStatus `json:"status,omitempty"`
}
type FeatureFlagSpec struct {
Enabled bool `json:"enabled"`
Percentage int `json:"percentage,omitempty"` // 灰度百分比
TargetUsers []string `json:"targetUsers,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
}
type FeatureFlagStatus struct {
ActiveClusters int `json:"activeClusters"`
LastSynced v1.Time `json:"lastSynced"`
Conditions []Condition `json:"conditions,omitempty"`
}
// 控制器Reconcile逻辑的核心
type FeatureFlagReconciler struct {
client.Client
Scheme *runtime.Scheme
K8sClient *kubernetes.Clientset
}
func (r *FeatureFlagReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
// 1. 获取FeatureFlag CRD实例
var ff FeatureFlag
if err := r.Get(ctx, req.NamespacedName, &ff); err != nil {
return reconcile.Result{}, client.IgnoreNotFound(err)
}
// 2. 业务逻辑:根据spec配置,更新相关配置或状态
// 例如:将功能标志配置同步到ConfigMap,供应用服务消费
configMap := r.generateConfigMap(&ff)
// 3. 应用配置
if err := r.applyConfigMap(ctx, configMap); err != nil {
// 更新状态为错误
ff.Status.Conditions = append(ff.Status.Conditions, Condition{
Type: "SyncFailed",
Status: "True",
Message: err.Error(),
})
_ = r.Status().Update(ctx, &ff)
return reconcile.Result{RequeueAfter: 30 * time.Second}, err
}
// 4. 更新状态
ff.Status.LastSynced = v1.NewTime(time.Now())
ff.Status.ActiveClusters = 1 // 实际应从集群注册表获取
ff.Status.Conditions = []Condition{{
Type: "Synced",
Status: "True",
}}
if err := r.Status().Update(ctx, &ff); err != nil {
return reconcile.Result{}, err
}
return reconcile.Result{}, nil
}
func (r *FeatureFlagReconciler) generateConfigMap(ff *FeatureFlag) *corev1.ConfigMap {
// 将FeatureFlag配置转换为应用可读的格式(如JSON字符串)
configData, _ := json.Marshal(map[string]interface{}{
ff.Name: map[string]interface{}{
"enabled": ff.Spec.Enabled,
"percentage": ff.Spec.Percentage,
"targetUsers": ff.Spec.TargetUsers,
},
})
return &corev1.ConfigMap{
ObjectMeta: v1.ObjectMeta{
Name: fmt.Sprintf("feature-flag-%s", ff.Name),
Namespace: ff.Namespace,
Labels: ff.Spec.Labels,
},
Data: map[string]string{
"config.json": string(configData),
},
}
}
// 主函数 - 启动控制器管理器
func main() {
// 1. 加载Kubernetes配置
config, err := rest.InClusterConfig()
if err != nil {
config, err = clientcmd.BuildConfigFromFlags("", filepath.Join(homeDir(), ".kube", "config"))
if err != nil {
panic(err.Error())
}
}
// 2. 创建Manager
mgr, err := manager.New(config, manager.Options{
Scheme: runtime.NewScheme(),
MetricsBindAddress: ":8080",
Port: 9443,
})
if err != nil {
panic(err)
}
// 3. 注册自定义资源Scheme
_ = apis.AddToScheme(mgr.GetScheme())
// 4. 设置Reconciler
k8sClient, _ := kubernetes.NewForConfig(config)
reconciler := &FeatureFlagReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
K8sClient: k8sClient,
}
if err := ctrl.NewControllerManagedBy(mgr).
For(&FeatureFlag{}).
Complete(reconciler); err != nil {
panic(err)
}
// 5. 启动Manager
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
panic(err)
}
}
这个示例展示了如何用Go构建一个Kubernetes Operator来控制功能标志。在实际的基础服务团队中,工程师需要编写大量类似的代码来实现配额管理、标签服务等。团队会广泛使用:
client-go和controller-runtime与Kubernetes API交互Helm进行服务打包和部署- 可能使用
sarama库与Kafka集成处理事件 - 通过
go-micro、connect-go或自定义gRPC/HTTP服务提供API
这个职位要求工程师不仅能够编写Go业务逻辑,还要深刻理解Kubernetes原语(Deployment、Service、ConfigMap、Secret)、控制器模式、声明式API以及分布式系统的运维(监控、日志、追踪、弹性)。代码质量、测试覆盖率(单元测试、集成测试、e2e测试)和自动化部署流水线也是日常工作的重点。

