Go/Golang DevOps运维开发实战集训营(2023版)
网盘地址:https://pan.baidu.com/s/1mldouX5nPMWoFHhW5CP8OQ 提取码: kd7r
腾讯微云下载地址: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="超级管理员"
下一篇:分布式理论
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传