欢迎光临散文网 会员登陆 & 注册

Go/Golang DevOps运维开发实战集训营(2023版)

2023-11-23 09:39 作者:bili_48219728313  | 我要投稿

学习地址1:https://pan.baidu.com/s/16vnJqtWw1oZlWAk31uXW6g 提取码:rl3i 

学习地址2:https://share.weiyun.com/fOjvMvBh 密码:32sf5s


随着服务器、业务系统越来越多,已经没有办法靠人来运维整个平台和业务了。可以试想,如果都需要人工干预完成工作,那得需要投入多少人力?当业务上线时,我们需要部署环境、部署项目;当发生问题时,我们人为地去感知问题后排查问题、定位问题,这时业务可能已经挂了很长时间。所以要基于对运维的理解构建起自动化、智能化运维平台现阶段,掌握一门开发语言已经是高薪运维工程师的必备技能,不会开发,你就不能提高运维工作效率!就不能充分理解公司业务流程!就不能帮助调试、优化!


Go是首选的开发语言,应用广泛;因为它出身名门谷歌,快速吸引大对于DevOps领域来说,批开发者的关注和使用,经过短短几年时间,已经挤进“开发语言排行榜”前10名,Go之所以能够取得如此出色的成绩,与他自身特点及发展密不可分,Go具有语法简洁、高并发、跨平台等优势!


Kubernetes 是一个用于自动化容器化应用程序的部署、扩展和管理的系统。它将构成应用程序的容器分组为逻辑单元,以便于管理和发现。Kubernetes 可以在不增加运维团队规模的情况下扩展和添加无限量的资源。它可以部署在本地,也可以在混合或公共云基础设施上运行。


在application.yml文件中,配置MongoDB连接。因为MongoDB自带数据库连接池,所以我们不需要在Java项目中重复配置连接池。

spring:

  ……

  data:

    mongodb:

      host: localhost

      port: 27017

      database: his

      #admin是MongoDB用于验证用户身份的逻辑库

      authentication-database: admin

      username: admin

      password: abc123456


因为SpringBoot Data中默认的RedisTemplate存在序列化机制的问题,向Redis里面保存Hash类型数据通常是乱码的,为了解决这个问题,我们需要自己定义配置类,修改RedisTemplate使用的序列化机制。


在com.example.his.api.config包中,创建RedisTemplateConfig类。

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;

import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration

public class RedisTemplateConfig {

    @Bean

    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<Object, Object> template = new RedisTemplate<>();

        template.setKeySerializer(new StringRedisSerializer());

        template.setValueSerializer(new StringRedisSerializer());

        template.setHashKeySerializer(new StringRedisSerializer());

        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        template.setConnectionFactory(factory);

        return template;

    }

}


因为Controller类用上@RestController注解之后,Web方法返回的对象会被自动转换成JSON对象,所以我们只需要声明一个封装类,让所有Web方法返回这个封装类的对象即可。除了公共属性之外,不同的Web方法要返回的业务数据也不尽相同,所以选择动态的结构才是最佳的方案,恰好HashMap允许我们随便添加数据,那就选择HashMap作为父类吧。在com.example.his.api.common包中,创建R.java类。

package com.example.his.api.common;


import org.apache.http.HttpStatus;

import java.util.HashMap;

import java.util.Map;


public class R extends HashMap<String, Object> {

    public R() {

        //默认创建的R对象中包含了公共的属性

        put("code", HttpStatus.SC_OK);

        put("msg", "success");

    }


    /*

     * 覆盖继承的put函数,添加Key-Value数据

     */

    public R put(String key, Object value) {

        super.put(key, value);

        //把自己返回,用于链式调用

        return this;

    }


    public static R ok() {

        return new R();

    }


    public static R ok(String msg) {

        R r = new R();

        r.put("msg", msg);

        return r;

    }


    public static R ok(Map<String, Object> map) {

        R r = new R();

        r.putAll(map);

        return r;

    }


    public static R error(int code, String msg) {

        R r = new R();

        r.put("code", code);

        r.put("msg", msg);

        return r;

    }


    public static R error(String msg) {

        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);

    }


    public static R error() {

        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");

    }


}

在user.vue页面中,我们要添加表格标签和分页组件标签,具体如下:

<div>

    <el-form :inline="true" :model="dataForm" :rules="dataRule" ref="form">

        ……

    </el-form>

    <el-table :data="data.dataList"

        :header-cell-style="{'background':'#f5f7fa'}" border

        v-loading="data.loading" @selection-change="selectionChangeHandle">

        <el-table-column type="selection" header-align="center"

            align="center" width="50" />

        <el-table-column type="index" header-align="center" align="center"

            width="100" label="序号">

            <template #default="scope">

                <span>{{ (data.pageIndex - 1) * data.pageSize + scope.$index + 1 }}</span>

            </template>

        </el-table-column>

        <el-table-column prop="name" header-align="center" align="center"

            min-width="100" label="姓名" />

        <el-table-column prop="sex" header-align="center" align="center"

            min-width="60" label="性别" />

        <el-table-column prop="tel" header-align="center" align="center"

            min-width="130" label="电话" />

        <el-table-column prop="email" header-align="center" align="center"

            min-width="240" label="邮箱" :show-overflow-tooltip="true" />

        <el-table-column prop="hiredate" header-align="center"

            align="center" min-width="130" label="入职日期" />

        <el-table-column prop="roles" header-align="center" align="center"

            min-width="150" label="角色" :show-overflow-tooltip="true" />

        <el-table-column prop="dept" header-align="center" align="center"

            min-width="120" label="部门" />

        <el-table-column prop="status" header-align="center" align="center"

            min-width="100" label="状态" />

        <el-table-column header-align="center" align="center" width="150"

            label="操作">

            <template #default="scope">

                <el-button type="text"

                    v-if="proxy.isAuth(['ROOT', 'USER:UPDATE'])"

                    @click="updateHandle(scope.row.id)">

                    修改

                </el-button>

                <el-button type="text"

                    v-if="proxy.isAuth(['ROOT', 'USER:UPDATE'])"

                    :disabled="scope.row.status == '离职' || scope.row.root"

                    @click="dismissHandle(scope.row.id)">

                    离职

                </el-button>

                <el-button type="text" :disabled="scope.row.root"

                    v-if="proxy.isAuth(['ROOT', 'USER:DELETE'])"

                    @click="deleteHandle(scope.row.id)">

                    删除

                </el-button>

            </template>

        </el-table-column>

    </el-table>

    <el-pagination @size-change="sizeChangeHandle"

        @current-change="currentChangeHandle" :current-page="data.pageIndex"

        :page-sizes="[10, 20, 50]" :page-size="data.pageSize"

        :total="data.totalCount"

        layout="total, sizes, prev, pager, next, jumper"></el-pagination>

</div>

这定义了一个Go程序中的包。包是Go语言的基本单元,而Go程序本质上是一组包。


在我们的示例中,它告诉Go编译器创建一个可执行文件,而不是库文件。如果你将包命名为不同的名称,则会遇到以下错误:


package command-line-arguments is not a main package

例如,如果你将其重命名为apple,如下所示:


package appleimport "fmt"func main() {

        fmt.Println("Hello, world")

}

如果运行go run main.go:


$ go run main.go

package command-line-arguments is not a main package

但是你仍然可以构建它,但它不会生成任何可执行文件:


$ go build main.go

$ ls

main.go

import { isUsername,isPassword } from '../../utils/validate';

……

function login() {

    if (!isUsername(loginForm.username)) {

        proxy.$message({

            message: '用户名不正确',

            type: 'error',

            duration: 1200

        });

    }

    else if (!isPassword(loginForm.password)) {

        proxy.$message({

            message: '密码不正确',

            type: 'error',

            duration: 1200

        });

    }

    else {

        const data = {

            username: loginForm.username,

            password: loginForm.password

        };

        proxy.$http('/mis/user/login', 'POST', data, true, resp => {

            if (resp.result) {

                const permissions = resp.permissions;

                const token = resp.token;

                //向浏览器storage保存令牌和权限列表

                localStorage.setItem('permissions', permissions);

                localStorage.setItem('token', token);

                //跳转页面

                router.push({ name: 'MisHome' });

            } else {

                proxy.$message({

                    message: '登陆失败',

                    type: 'error',

                    duration: 1200

                });

            }

        });

    }


}

接下来,我将把我搭建该技术框架的入门过程记录下来:


过程中遇到很多坑,只要硬着头皮上就没什么能把你阻挡,让我们一起go!go!go!

需求:在日常开发过程中,需要频繁的修改业务逻辑,然后需要部署到服务器上供QA测试。这个过程对于大多数开发人员来说不是难事,但是这个重复性的过程很浪费开发人员的时间,我们希望达到,只要我们将改好的业务逻辑代码commit & push,自动部署更新到服务器上并启动。就可以测试了。

/*!mycat: sql=

SELECT DISTINCT u.id,

       u.username,

SELECT GROUP_CONCAT( role_name separator "," ) 

FROM tb_role 

WHERE JSON_CONTAINS ( u.role, CONVERT (id, CHAR) ) 

) AS roles

FROM tb_user u

JOIN tb_role r ON JSON_CONTAINS ( u.role, CONVERT (r.id, CHAR) )

WHERE  u.name="超级管理员"

*/

SELECT DISTINCT u.id,

       u.username,

SELECT GROUP_CONCAT( role_name separator "," ) 

FROM tb_role 

WHERE JSON_CONTAINS ( u.role, CONVERT (id, CHAR) ) 

) AS roles

FROM tb_user u

JOIN tb_role r ON JSON_CONTAINS ( u.role, CONVERT (r.id, CHAR) )

WHERE  u.name="超级管理员"


Go/Golang DevOps运维开发实战集训营(2023版)的评论 (共 条)

分享到微博请遵守国家法律