精华内容
下载资源
问答
  • 容器化最佳实践
    2018-07-09 11:35:57

    Dockerfile容器化应用最佳实践

    将一个应用容器化,就是将这个应用构建成Docker镜像,然后以Docker容器方式来运行。

    构建Docker镜像就是编写Dockerfile,并通过docker build 命令构建成Docker镜像。

    可以用”小、快、好、省“来概括Dockerfile的最佳实践。

    最佳实践

    让构建出来的镜像尽可能”小“

    Why?

    小的镜像的好处包括构建镜像快,占用磁盘空间小,网络传输快(比如docker pulldocker push 时速度快)。

    How?

    • 选择适合的尽量小的基础镜像

      比如,你要从Linux操作系统基础镜像开始构建,可以参考下表来选择合适的基础镜像:

    镜像名称大小使用场景
    busybox1.15MB临时测试用
    alpine4.41MB主要用于测试,也可用于生产环境
    centos200MB主要用于生产环境,支持CentOS/Red Hat,常用于追求稳定性的企业应用
    ubuntu81.1MB主要用于生产环境,常用于人工智能计算和企业应用
    debian101MB主要用于生产环境

    让构建镜像过程尽可能“快”

    Why?

    加快构建的好处不言而喻,比如加快构建Docker镜像环节可以提升整个部署流水线的效率。

    How?

    • 使用清洁的构建上下文(build context)

      Docker CLI是由给定一个目录或者URL作为构建上下文的,在镜像构建之前会将该上下文发送到Docker Daemon。建议在一个新的目录里创建Dockerfile,然后在该目录里只添加镜像包含的文件。这为docker build命令提供了一个更加清洁的上下文并且允许更快地构建镜像。否则,扫描带有多个文件的目录将不必要地减慢构建速度。

      参考文档:https://docs.docker.com/engine/reference/builder/#usage

    • 利用构建时缓存(build cache)

      Docker build构建镜像时会重复使用已经构建过的中间层作为缓存来加快构建过程。而Docker build构建时是按照Dockerfile顺序构建的,因此需要将不经常变化的生成层的命令放在前面,把经常变化的生成层的命令放在后面。

      参考文档:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache

    让镜像变得”好用“

    Why?

    好用的镜像,造就好用的容器。好用的容器是指可以使用Docker 标准命令前后台运行,传入运行时环境变量控制容器行为,传入运行命令替换缺省命令,优雅的停止,方便查看日志和进入容器内部调试。

    How?

    让构建镜像变得”省事、省心“

    Why?

    Dockerfile越复杂,越容易出错;Dockerfile有问题,运行的容器会有安全隐患。

    How?

    • 选择高级别基础镜像

      尽量使用高级别基础镜像来简化编写Dockerfile的工作,比如为Java应用容器化使用openjdk基础镜像,而不是从alpine 操作系统基础镜像开始构建。

    • 保持Dockerfile尽可能简单

      参考Docker官方和其它一些好的开源软件的Dockerfile,让Dockerfile尽量保持简单,可读。

    • 使用经过安全扫描的基础镜像

      经过安全扫描的基础镜像,可以让容器运行在一个安全的环境。

    FAQ

    Q: ARGENV 命令的区别。

    A: ARG 支持在构建镜像时(build-time)修改参数的值,比如docker build --build-arg var=xxx

    ENV 支持在运行容器时(run-time) 修改参数的值,比如docker run -e var=yyy

    Q: ADDCOPY 命令的区别。

    A: 推荐使用COPY命令。

    Q: Docker build的cache问题。

    A: ADDCOPY 命令利用cksum来检查同名文件是否存在在缓存中,但是对cksum的计算不包括last-modified time和last-accessed time,有可能导致缓存机制失效。如果你的应用每次都基于一个同名文件,需要注意这个问题。

    https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache

    Q: RUN , CMDENTRYPOINT的区别。

    A: RUN 命令是在docker build 构建时被执行,在容器运行时不会被执行。

    CMDENTRYPOINT 命令是在docker run 运行容器时被执行,在容器构建时不会被执行。

    Docker缺省的ENTRYPOINT是/bin/sh -c

    参考文档

    更多相关内容
  • 容器是一种轻量级的虚拟技术,拥有持续集成、版本控制、可移植性、隔离性和安全性等优点,越来越多的应用跑在容器里面。但也有其缺陷,并不是所有场景都适合如高性能计算,已经满负荷运行的应用没有必要虚拟,...
  • 陈靖贤,去哪儿网 DevOps 产品经理,目前主要负责在去哪儿传播 DevOps 文化,调查、导入和开发流程、工具、平台的最佳实践,帮助公司以更快的速度交付软件,降低风险,降低运营成本 近几年随着云原生技术的成熟,...

    作者:邹晟,去哪儿网基础架构团队高级 DevOps 工程师,现主要负责 CI/CD 平台开发与维护,云原生技术研究与实现。同时也是 KubeSphere Talented Speaker。 陈靖贤,去哪儿网 DevOps 产品经理,目前主要负责在去哪儿传播 DevOps 文化,调查、导入和开发流程、工具、平台的最佳实践,帮助公司以更快的速度交付软件,降低风险,降低运营成本

    近几年随着云原生技术的成熟,Qunar 为了实现整个技术体系的演进,Qunar 在 2021 年向云原生迈出了第一步 -- 容器化 。 落地过程包括了价值评估、基础设施建设,CI/CD 流程改造、中间件的适配、可观测性工具、应用自动化迁移等。迁移过程涉及到了 3000 个应用左右,涉及千人级研发团队,是一个难度非常大的系统工程。这篇文章会讲述迁移过程涉及到的 CI/CD 模型改造、自动化应用容器化改造等最佳实践。

    背景

    容器化落地前的业务痛点

    在容器化落地之前,我们经常会听到来自不同角色的各种各样的抱怨与吐槽:

    • 领导层的声音:服务器资源和维护成本太高了,我们必须降低成本!
    • OPS 的声音:有一台宿主故障了,需要把上边的服务赶快恢复!
    • QA 的声音:测试环境好好的,为啥上线失败了?
    • 研发人员的声音:业务高峰来啦,资源不够用啦!赶快去扩容!哎! 扩容太慢了。

    造成这些问题的因素主要包含:资源利用率、服务无法自愈、测试环境与线上环境不一致,运行环境缺少弹性能力。

    企业所面临的商业环境是复杂多变的,当今环境的竞争异常激烈,而且不再是大鱼吃小鱼,而是快鱼吃慢鱼。通用电气前 CEO Jack Welch 曾经说过:“如果外部变化的速度超过内部变化的速度,终结就不远了”。我们的企业如何能在这样的环境中存活发展呢?各个企业都在不断的探索和实践中前行。今年来,云原生技术日趋成熟,已经被广大企业广泛接受并采用。云原生技术可以帮助企业降低成本,加快业务迭代,对赋能企业的产业升级提供强有力的技术支撑。容器化作为云原生技术之一,成为 Qunar 拥抱云原生进行技术升级的重要一环。

    容器化落地过程的挑战与应对

    全司范围内进行容器化全面落地并不是一件容易的事,我们面临了重重困难,但是我们为了最终目标的达成,想尽一切办法去一一化解。

    首先,涉及部门多: 容器化迁移涉及 OPS、基础架构、数据组等基础设施部门以及 20+业务部门。这么多的部门达成对目标的一致认同,并保持行动的协调一致是非常不容容易的。好在我们这个项目得到了公司高层的认可,并将此作为 2021 年的企业级目标。在企业级目标的引领下,各个部门协同一致,通力配合保障了项目的成功。

    其次, 改造范围大:由于历史原因,我们的服务多是有状态的。从中间件、发布系统到网络、存储、日志收集、监控告警以及业务服务本身等等各个环节对机器名、IP、本地存储等状态有着强依赖。而容器本身是无状态的,这就意味着我们需要从基础设施、发布、运维的工具、平台进行整体改造。针对这重重问题,我们进行了一一列举,逐个击破,最终满足容器化迁移的条件。

    再次,业务迁移成本高:本次迁移涉及应用数量大概有 3000 多个,迁移过程需要对应用进行升级改造、测试回归及上线,这个过程将花费大量人力。如何降低业务的迁移成本呢?我们支持将大部分的适配工作在中间件层进行统一支持,然后支持在业务代码中进行中间件的自动升级,自动进行容器化迁移,通过持续交付流水线对迁移过程中的变更进行自动化的测试与验证,经过容器与虚机灰度混部观察等手段大大降低了业务人工迁移的成本。

    最后,学习成本高:我们的研发团队有千人级的规模,对于新技术的引入与升级,研发同学需要花费额外的成本进行学习和使用。为了降低大家的学习成本,我们通过平台工具屏蔽差异性操作以及技术细节,通过可视化配置、引导式操作,优化持续交付流程等方式来降低业务的学习成本。

    容器化后的收益

    经过 2021 年一年时间,我们完成了容器化基础设施建设,工具平台的升级改造以及 90%应用的容器化迁移(应用总数 3000+)。从效果数据来看,容器化虚拟比例从 1:17 提升到 1:30, 资源利用率提升 76%;宿主运维时间之前以天为单位,容器化以后变成了分钟级,运维效率提升了 400 倍;由于容器化启动时间的缩短以及部署策略的优化,应用的交付速度提升 40%;K8S 集群提供了服务自愈能力,应用运行过程中平均自愈次数达到 2000 次/月;另外,容器化落地也为公司进行下一步云原生技术的深入推广与落地奠定了基础。

    持续交付

    项目研发流程

    Qunar 采用了业务驱动的价值流与以应用为中心的持续交付工作流的双流模型。企业以业务价值交付为目标,在交付过程中,各个阶段的交付物会在多个角色中的流转,在流转过程中难免会出现不同程度的浪费。为了有效对价值交付的效率进行有效度量与优化提升,我们不仅仅需要关注开发过程中的效率提升,还需要关注开发前的效率提升。我们将持续交付工作流的流转与价值流的流动进行联通,希望可以实现从项目域、开发域、测试域到运维域的流程自动流转的。但是在容器化之前,由于环境不一致、各阶段配置的不一致性等原因,导致交付过程中,交付流程在各阶段间流转时不可避免的存在人工干预的情况。容器化之后,我们参照云原生的 OAM 模型,对应用进行了规范化定义,建立应用画像,统一术语,消除数据孤岛,使流程可以顺畅高速流转。

    应用画像

    针对上面项目的流程流转,最重要的一个连接器就是 App code, 因此我们也针对它做了抽象,画像定义:

    开发人员在面对开发、测试和生产等复杂的环境时、需要编写和维护多分应用部署配置文件;运维人员需要理解和对接不同的平台,管理差异巨大的运维能力和运维流程。

    参照云原生中的开发应用模型原则,我们通过建立应用画像,指定应用的标准化定义。我们开发和运维人员通过标准的应用描述进行协作,轻松实现应用的“一键部署”、“模块化运维”,无须纠结于服务的开通配置和接入工作,提升应用交付与运维的效率和体验。

    借助应用的规范化,将应用平台进行统一化与规范化。我们将原来的以资源为中心,转变为以应用为中心。平台架构如下:

    多云协同

    基础设施资源层: 底层资源既支持 KVM 也支持容器,这些资源都是跨机房部署。同时为了让底层资源更具弹性,我们对接了公有云。

    平台层: 基于 K8s、KubeSphere 多集群管理、Service Mesh、Serverless 等云原生技术来提高技术先进性和技术的架构演进。

    资源调度:

    • 会考虑节点的亲和性: 机器配置, 普通磁盘、SSD, 千兆网卡、万兆网卡
    • 容量预估:发布前预计算, 如果资源不足,禁止发布
    • 机器负载:尽可能让集群所有节点负载均衡

    双 Deployment 发布

    优点:

    1. 降低了操作复杂度, 操作只包含 create, scale, delete。 而单个 Deployment 更新过程可能会有更新过程失败,卡在中间状态, 升级和回滚都无法进行的时候
    2. 支持分批操作, 发布流程更可控
    3. 更新 Deployment label 变为可能

    缺点:

    • 需要记录和控制 Deployment 状态,操作相对于单 Deployment 会相对复杂一些

    业务应用自动迁移方案

    这次容器化需要迁移 3000+ 的应用,为了减少开发测试人员的迁移成本,我们提供了一个自动升级 Java SDK、自动迁移容器的方案。

    自动迁移方案:

    1. 前置校验

      • 验证是否引用了自动升级的 SDK
      • 编译阶段验证是否有不适合容器化场景使用的 Java 方法
        比如验证是否调用了依赖 hostname 的方法,如果有的化会提前提示容器发布失败。 因为容器场景 ip 变化是常态,hostname 也是经常变化的,过去业务线依赖 hostname 做业务逻辑区分的会有问题
    2. 测试环境验证

      自动升级 SDK 后在测试环境发布并验证应用的容器化升级是否 ok

    3. 线上环境验证

      • 灰度发布到线上,暂时不接入流量
      • 通知应用 owner 做自动化测试
      • 验证没问题,则接入线上流量
    4. 混合部署

      • 线上容器和 KVM 同时部署,流量比例根据实例比例调配
      • 关注指标与告警
    5. 容器接入全部流量

      容器全量部署,KVM 容量全部摘除 (KVM 会保留几天观察)

    6. 观察

      关注容器全量后的业务监控指标,如果发现异常及时迁回 KVM

    7. KVM 回收

      为了快速腾出资源到 K8s 集群,我们会在规定期限内通知应用的 owner 回收机器, 如果超过规定时间(7 天),遗留的 KVM 资源回被强制回收

    自动升级 SDK 流程

    tcdev bom 是公司统一管理二方包和三方包依赖的公共基础组建,绝大多数的 Java 应用都会使用这个组建,因此我们的升级 SDK 方案就是在编译过程自动检测并升级 tcdev 版本。

    升级 SDK 的前置条件

    前提说明
    二方包、三方包统一管理Super POM, tcdev-bom: 核心组件统一管理、升级
    质量门禁静态代码检查, 版本兼容性校验, 做好上线前的质量控制
    自动验证组件升级后的兼容性通过批量跑自动化测试,对比 master 分支和升级后的分支
    发布的超管权限自动升级、灰度、上线

    升级步骤

    事后复盘的时候,很多业务同学也都反馈这个自助升级迁移的方式为他们节省了大量时间,价值非常明显,得到了大家的认可。

    总结

    在云原生转型的过程中,如何让业务更顺畅的享受到云原生的红利是非常有挑战的,希望这篇文章能给刚步入云原生的同学带来一些启发。云原生的路上,我们一起共勉!

    本文由博客一文多发平台 OpenWrite 发布!

    展开全文
  • 应用容器化最佳实践2020.11.14Dehua Yedehua@rancher.com© Copyright 2020 Rancher Labs. All Rights Reserved. Confidential云原生应用云原生(Cloud Native)是一种充分利用云计算优势,用于构建和部署应用的方式...
  • 因为在之前一篇文章一文零基础教你学会 Docker 入门到实践中也已经讲解的很详细了,不清楚的可以点击链接回头在重新看下,本篇重点是介绍 Node.js 项目如何进行 Docker 容器化及一些实践优化,还有一些常见的问题,...
  • Spring cloud 是当下最炙手可热的微服务套件,我们将介绍如何整合Docker容器达到高效快捷的构建发布 采用了dockerfile-maven-plugin插件发布镜像到远程docker主机,该部分详细教程请看 使用Maven插件快捷打包发布...

    Spring cloud 是当下最炙手可热的微服务套件,我们将介绍如何整合Docker容器达到高效快捷的构建发布
    采用了dockerfile-maven-plugin插件发布镜像到远程docker主机,该部分详细教程请看 使用Maven插件快捷打包发布远程Docker镜像

    添加docker插件依赖

    如何开放远程docker主机远程控制端口请看 使用Maven插件快捷打包发布远程Docker镜像

    # 可以直接在父工程pom内添加插件,各子项目将自动继承插件依赖
    <build>
            <plugins>
                <plugin>
                    <groupId>com.spotify</groupId>
                    <artifactId>dockerfile-maven-plugin</artifactId>
                    <version>1.4.0</version>
                    <configuration>
                        <repository>${docker.image.prefix}/${project.artifactId}</repository>
                        <buildArgs>
                            <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                        </buildArgs>
                    </configuration>
                </plugin>
            </plugins>
    </build>

    添加Dockerfile文件

    需要为各需要发布为docker镜像的服务项目在其根目录添加Dockerfile文件

    # dockerfile 基础配置
    FROM daocloud.io/library/java:8u40-b22
    VOLUME /tmp
    ARG JAR_FILE
    ADD ${JAR_FILE} /app/app.jar
    WORKDIR /app/
    # 该镜像需要暴露的接口
    EXPOSE 8889
    ENTRYPOINT ["java","-jar","./app.jar"]

    执行发布镜像

    mvn clean package dockerfile:build -DskipTests

    这里写图片描述
    可以看到微服务中的各服务项目都被已经被发布到了远程docker镜像

    运行

    将各服务都跑起来

    docker run -d -p 8889:8889 --name hnister-eureka-server hnister/hnister-eureka-server

    但现在还有一个问题就是如何引入mysql等组件到docker中呢

    数据库等服务的引入

    如何构建一个外部可访问的mysql docker容器请看:Docker 构建Mysql容器并对外提供服务

    容器间网络互通

    现在各镜像已经构建完毕,如何让各容器相互访问呢,以前docker采用link的方式,但这种方式已经不被推荐了。
    我们可以采用network来方便快捷的达成我们所期望的效果;

    创建一个新的network

    创建新network

    docker network  create hnister

    这里写图片描述
    network被创建成功,在运行容器时指定network

    # 通过--network 结合 --network-alias 指定网络
    docker run -d -p 8889:8889 --name hnister-eureka-server --network hnister hnister/hnister-eureka-server
    docker run -d -p 8889:8889 --name hnister-mysql --network hnister --network-alias mysql.hnister.cn mysql

    对已经运行的容器链接到network,而其他服务在加入了该network后可以通过alias来访问主机如链接到数据库mysql

    jdbc:mysql://mysql.hnister.cn/hnister

    对于已经启动的容器可以使用命令来加入自建network

    docker network connect hnister hnister-eureka-server

    这样所有的容器就都在一个network内了可以相互访问

    展开全文
  • 微服务应用容器化场景最佳实践.docx
  • 金融行业应用容器化转型的最佳实践.pdf
  • 金融行业应用容器化转型的最佳实践.docx
  • 这些内容直接遵循的就是容器化落地的最佳实践.docx
  • 12月9日,在云栖计算之旅线下沙龙上,阿里云容器服务团队的高级研发工程师秦妤嘉分享了《基于容器技术的DevOps探索》。首先介绍了DevOps和CD,接着分析了Docker如何打破传统CD壁垒,最后讲解了怎样从零开始搭建一个...
  • nodejs-docker-最佳实践 使用Docker容器化Node.js Web应用程序的最佳实践
  • Docker+Kubernetes(k8s)微服务容器化实践 Docker+Kubernetes(k8s)微服务容器化实践课程连接:https://coding.imooc.com/learn/list/198.html 第1章 初识微服务 1-1 微服务-导学 容器技术的成熟为微服务的落地提供了...

    Docker+Kubernetes(k8s)微服务容器化实践

    Docker+Kubernetes(k8s)微服务容器化实践课程连接:https://coding.imooc.com/learn/list/198.html

    第1章 初识微服务

    1-1 微服务-导学

    容器技术的成熟为微服务的落地提供了基础,轻量化的容器是微服务运行的最佳环境。
    微服务只有在容器(Docker)环境下,再结合有效服务编排框架(K8s),才能使持续集成快速交付变成可能。

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    课程内容
    在这里插入图片描述

    1. 开发: 业务场景架构图

    在这里插入图片描述

    1. 部署:
      在这里插入图片描述
    2. 服务编排:
      在这里插入图片描述
      在这里插入图片描述

    自动化持续集成和部署

    从代码提价到服务部署自动化
    在这里插入图片描述
    在这里插入图片描述

    1-2 软件架构的进化 (11:40)

    1-3 什么是微服务

    在这里插入图片描述

    1-4 画出微服务架构图

    在这里插入图片描述

    1-5 微服务架构的优势和不足

    在这里插入图片描述

    第2章 微服务带来的问题及解决方案分析

    2-1 微服务架构带来的问题

    2-2 微服务间如何通讯

    通信模式:
    在这里插入图片描述

    在这里插入图片描述
    通信协议:
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    2-3 服务发现、部署更新和扩容

    1. 服务发现:

    我们的服务对外表现的形式一般是ip+端口号,服务发现的本质就是让服务调用者/客户端如何知道服务提供的ip和端口号

    一般单体服务发现(Eginx)
    但不是自动的发现,nginx转发ip和端口需要手动配置
    在这里插入图片描述
    微服务中的服务发现

    在这里插入图片描述

    在这里插入图片描述

    2. 服务部署

    单体项目部署
    在这里插入图片描述

    微服务部署
    服务编排

    在这里插入图片描述

    在这里插入图片描述

    2-4 springboot&springcloud(上)

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    2-5 springboot&springcloud(下) (12:17)

    第3章 微服务开发

    3-1 微服务业务分析

    在这里插入图片描述

    3-2 Thirft安装和验证 (08:20)
    3-3 Python开发信息服务 (24:28)
    3-4 开发用户服务(上) (15:21)

    3-5 开发用户服务(下)

    mapper接口

    package com.imooc.user.mapper;
    
    import com.imooc.thrift.user.UserInfo;
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    
    /**
     * Created by Michael on 2017/10/28.
     */
    @Mapper
    public interface UserMapper {
    
        @Select("select id,username, password, real_name as realName," +
                "mobile, email from pe_user where id=#{id}")
        UserInfo getUserById(@Param("id")int id);
    
    
        @Select("select id,username, password, real_name as realName," +
                "mobile, email from pe_user where username=#{username}")
        UserInfo getUserByName(@Param("username")String username);
    
    
        @Insert("insert into pe_user (username, password, real_name, mobile, email)" +
                "values (#{u.username}, #{u.password}, #{u.realName}, #{u.mobile}, #{u.email})")
        void registerUser(@Param("u") UserInfo userInfo);
    
    
        @Select("select u.id,u.username,u.password,u.real_name as realName," +
                "u.mobile,u.email,t.intro,t.stars from pe_user u," +
                "pe_teacher t where u.id=#{id} " +
                "and u.id=t.user_id")
        UserInfo getTeacherById(@Param("id")int id);
    }
    
    

    Services使用

    package com.imooc.user.service;
    
    import com.imooc.thrift.user.UserInfo;
    import com.imooc.thrift.user.UserService;
    import com.imooc.user.mapper.UserMapper;
    import org.apache.thrift.TException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    /**
     * Created by Michael on 2017/10/28.
     */
    @Service
    public class UserSerivceImpl implements UserService.Iface {
    
    
        @Autowired
        private UserMapper userMapper;
    
        @Override
        public UserInfo getUserById(int id) throws TException {
    
            return userMapper.getUserById(id);
        }
    
        @Override
        public UserInfo getTeacherById(int id) throws TException {
            return userMapper.getTeacherById(id);
        }
    
        @Override
        public UserInfo getUserByName(String username) throws TException {
            return userMapper.getUserByName(username);
        }
    
        @Override
        public void regiserUser(UserInfo userInfo) throws TException {
            userMapper.registerUser(userInfo);
        }
    }
    
    

    3-6 开发用户EdgeService_A

    在这里插入图片描述
    使用Docker启动Redis
    在这里插入图片描述

    SpringBoot 整合Redis

    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
    package com.imooc.user.redis;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    
    /**
     * Redis缓存配置类
     */
    @Configuration
    @EnableCaching
    public class RedisConfig extends CachingConfigurerSupport {
    
        @Value("${spring.redis.host}")
        private String host;
        @Value("${spring.redis.port}")
        private int port;
        @Value("${spring.redis.timeout}")
        private int timeout;
    
        //缓存管理器
        @Bean
        public CacheManager cacheManager(RedisTemplate redisTemplate) {
            RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
            //设置缓存过期时间
            cacheManager.setDefaultExpiration(10000);
            return cacheManager;
        }
    
        @Bean
        public JedisConnectionFactory redisConnectionFactory() {
            JedisConnectionFactory factory = new JedisConnectionFactory();
            factory.setHostName(host);
            factory.setPort(port);
            factory.setTimeout(timeout);
            return factory;
        }
    
        @Bean
        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory){
            StringRedisTemplate template = new StringRedisTemplate(factory);
            setSerializer(template);//设置序列化工具
            template.afterPropertiesSet();
            return template;
        }
    
        private void setSerializer(StringRedisTemplate template){
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            template.setValueSerializer(jackson2JsonRedisSerializer);
        }
    }
    
    
    package com.imooc.user.redis;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Component;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * Created by Michael on 2017/10/30.
     */
    @Component
    public class RedisClient {
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        public <T> T get(String key) {
            return (T)redisTemplate.opsForValue().get(key);
        }
    
        public void set(String key, Object value) {
            redisTemplate.opsForValue().set(key, value);
        }
    
        public void set(String key, Object value, int timeout) {
            redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
        }
    
        public void expire(String key, int timeout) {
            redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
        }
    
    }
    
    
            //2. 生成token
            String token = genToken();
    
            //3. 缓存用户
            redisClient.set(token, toDTO(userInfo), 3600);
    
            return new LoginResponse(token);
    
        @RequestMapping(value="/authentication", method = RequestMethod.POST)
        @ResponseBody
        public UserDTO authentication(@RequestHeader("token") String token) {
    
            return redisClient.get(token);
        }
    

    3-7 开发用户EdgeService_B (28:54)
    3-8 开发用户EdgeService_C (25:24)
    3-9 开发用户EdgeService_D (12:53)
    3-10 dubbo入门操练(上) (13:45)
    3-11 dubbo入门操练(下) (13:48)
    3-12 开发课程服务 (28:31)
    3-13 开发课程EdgeService (21:11)
    3-14 APIGatewayZuul (14:56)

    第4章 服务编排前奏

    在这里插入图片描述

    4-1 服务docker化(上)

    Docker官网

    去Docker官网下载一个基础的java镜像
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    Dockerfile 文件
    在这里插入图片描述

    FROM openjdk:7-jre
    MAINTAINER xxx xxx@imooc.com
    
    COPY target/user-thrift-service-1.0-SNAPSHOT.jar /user-thrift-service.jar
    
    ENTRYPOINT [ "java", "-jar", "/user-thrift-service.jar" ]
    

    在这里插入图片描述
    写脚本方:直接打包后编译成Docker镜像
    在这里插入图片描述

    在这里插入图片描述

    4-2 服务docker化(下) (20:30)

    4-3 docker下的服务通讯(上)

    在这里插入图片描述

    docker-compose.yml

    version: '3'
    
    services:
      message-service:
        image: message-service:latest
    
      user-service:
        image: user-service:latest
        command:
        - "--mysql.address=192.168.1.8"
    
      user-edge-service:
        image: user-edge-service:latest
        links:
        - user-service
        - message-service
        command:
        - "--redis.address=192.168.1.8"
    
      course-service:
        image: course-service:latest
        links:
        - user-service
        command:
        - "--mysql.address=192.168.1.8"
        - "--zookeeper.address=192.168.1.8"
    
      course-edge-service:
        image: course-edge-service:latest
        links:
        - user-edge-service
        command:
        - "--zookeeper.address=192.168.1.8"
    
      api-gateway-zuul:
        image: api-gateway-zuul:latest
        links:
        - user-edge-service
        - course-edge-service
        ports:
        - 8080:8080
    
    

    在这里插入图片描述

    4-4 docker下的服务通讯(下) (11:24)
    4-5 镜像仓库 (23:44)
    4-6 三大平台扬帆起航 (02:49)
    第5章 服务编排-Mesos
    5-1 了解Mesos (17:45)
    5-2 画出Mesos集群架构图 (07:04)
    5-3 集群环境搭建_A (16:20)
    5-4 集群环境搭建_B (14:58)
    5-5 集群环境搭建_C (13:27)
    5-6 调整微服务适应Mesos (11:55)
    5-7 微服务部署_A (11:41)
    5-8 微服务部署_B (15:52)
    5-9 微服务部署_C (15:17)
    第6章 服务编排-DockerSwarm
    6-1 了解Swarm (16:41)
    6-2 集群环境搭建(上) (18:18)
    6-3 集群环境搭建(下) (17:46)
    6-4 调整微服务及服务配置 (16:36)
    6-5 微服务部署 (25:30)

    第7章 服务编排-Kubernetes

    7-1 了解kubernetes(上)

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    7-2 了解kubernetes(下)

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    7-3 环境搭建前奏

    GItHub: kubernetes入门,包括kubernetes概念,架构设计,集群环境搭建,认证授权等。
    在这里插入图片描述
    在这里插入图片描述

    7-4 预先准备环境 (15:08)
    7-5 基础集群部署(上) (12:58)
    7-6 基础集群部署(下) (16:05)
    7-7 小试牛刀 (27:22)
    7-8 kube-proxy和kube-dns (21:17)
    7-9 理解认证、授权 (13:22)
    7-10 为集群添加认证授权(上) (13:58)
    7-11 为集群添加认证授权(下) (26:53)
    7-12 再试牛刀 (11:41)
    7-13 部署我们的微服务 (23:42)

    第8章 CICD和DevOps

    8-1 了解CICD和DevOps

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    DevOps是CICD的延申,CICD是DevOps的基础核心, DevOps是CICD的落地实现
    在这里插入图片描述

    CI(持续集成) 目前比较流行的持续集成工具: Jenkins
    在这里插入图片描述

    持续集体的CICD的具体步骤:

    在这里插入图片描述

    8-2 准备GitLab和Jenkins (18:09)
    8-3 CICD实践(上) (18:42)
    8-4 CICD实践(下) (19:56)
    第9章 课程总结
    9-1 -课程总结 (05:10)

    展开全文
  • • 业务全面亏联网,带来访问不确定性 不可预测的系统的宕机。 • 系统频繁上线,运维疲亍奔命 据说有个兄弟2016年一年通宵加班次数达到72次。 • 系统微服务,运维复杂度极大提高 人手不够,一个人管一堆系统,...
  • 阿里云资深技术专家易立通过阿里云容器服务,分享容器技术落地的最佳实践,希望能够帮助同学们更好地理解容器技术和云原生理念,合理地设计上云架构,充分发挥云的价值。(文末推荐:2020 阿里巴巴研发效能峰会) ...
  • 今天我主要讲四个内容,我做内容规划的时候其实...这里会介绍行业内的一些最佳实践。第四部分,测试结果自动分析服务的设计与应用。全回归测试的用例数量往往很多,很多大型企业全回归测试用例数量会达到好几万这样的
  • 容器化监控方案参考

    千次阅读 2022-03-17 10:48:00
    本篇为我在做公司容器化监控平台选型时的一些调研思路和资料记录,希望可以给到大家启发和帮助。 阅读本文,你可以了解到: 现阶段容器化方案总结 容器化监控曾经出现过的几种方案: 1/ Heapster[1] + ...
  • 身为让容器应用实现大规模工业生产的一大功臣,过去几年,Kubernetes 势头迅猛,BAT、京东、美团、字节都走上了全域容器化部署以及云原生架构的康庄大道。而作为支撑阿里万亿级应用背后...
  • VMware 云管平台助力数字转型。vCMP5 Based on SDDC。 1、VMware云计算解决方案一览 2、容器云 3、PSO 最佳实践 4、vRA&UP功能介绍

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 50,711
精华内容 20,284
热门标签
关键字:

容器化最佳实践