php| php 微服务之旅: devops

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
云原生网关 MSE Higress,422元/月
简介: 本篇属于 `PHP 微服务之旅` 系列, 此系列会持续更新, 敬请期待.

本篇属于 PHP 微服务之旅 系列, 此系列会持续更新, 敬请期待.

如果说 微服务应用 对比 传统巨石应用 最大的难点在于 基础设施 的复杂度上, 那么本篇就是要抛砖引玉, 提供一个完整的 devops 实例, 证明一个简单的事实:

使用 devops 后, 微服务的开发也能有 传统巨石应用 的简单高效.

先提前预告一下效果, 对于一个参与到项目的开发而言:

  • 本地只需要安装 git/docker, 容器启动后, 项目所需的开发环境全都有
  • 开发者除了正常编写代码, 项目的 CI/CD 会在代码提交后自动触发, 开发者完全不用分心

devops 流程一览

  • github 私有库 / gitlab 私有部署
  • 绑定 Travis CI 持续集成
  • 绑定 aliyun 容器镜像服务(cr), 设置自动构建规则
  • 绑定 aliyun 容器服务swarm(cs), 设置镜像构建后自动部署
  • 绑定 aliyun 日志服务(sls), 设置容器日志自动投递到日志服务

下面详细讲解下各部分

git

类似对比 git 与 svn 这种事, 不会再出现在我的 blog 中, 有种去翻历史尘埃的感觉, 大概比较适合 技术史 一类的文章.

记一些 git 常用的功能吧:

  • git add/commit/stash/push 这些基础命令不熟悉的话, 估计对应的 工作去/暂存区/提交区/远程分支 这些基础概念也不熟, 这是基础, 自行百度补
  • git branch/checkout/merge 这些分支相关命令, 也要很熟悉
  • git tag 只是在 commit 上做了一个标记, 建议使用统一的格式
  • git clone 有 2 种方式, ssh 需要配置公钥, https 需要账号密码认证, 可以使用 git config --global credential.helper "store" 记住账号密码
  • git 是分布式的, 本地就是一个完整的仓库(repository), 通常会添加一个远程仓库来完成大家的协作

    • 通常这个远程地址命名为 origin, 可以通过 git remote add origin url-xxx 来添加
    • 当然远程分支是可以修改的 git remote set-url origin url-xxx
    • 当然远程分支可以有多个

      • 比如 github 提 PR, 需要 fork 原项目, fork 的出来的项目除了有远程分支 origin 外, 还会多一个名为 upstream 的远程分支对应原项目
      • 当然也可以添加更多, 比如 git remote set-url gitee url-xxx, 添加一个国内的 git 库, 速度更快
  • 推荐使用的 git 客户端: github desktop

    • 命令行才是最好用的, 但是有一个场景除外, git diff, 强调一点, 自己写的代码, 自己一定要 review
    • github 自家的, 所以提 PR 使用快捷键 cmd-r 就可以了, 贼爽, 推荐给坚持开源的小伙伴
  • 开发过程中通常使用 MR(merge request), 尽量做好 自测/code-review/CI, 从而尽量不发生 revert, 避免不了也不要慌, gitlab revert MR 体验贼好
  • 添加 alias, 为 git 命令行操作加速

git alias 推荐:

alias gc='git checkout'
alias gb='git branch'
alias gt='git tag'
alias gs='git status'
alias gd='git diff'
alias gl="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
alias ga='git add -A'
alias gm='git merge'
alias gp='git pull'
alias gcl='git clone --progress'
# alias gp='git pull --rebase'
alias gpp='git pull;git push'
alias gco='git commit -am'
alias gca='git commit -am "update";git pull;git push'

# 打 tag 也可以很轻松
function gtt
    set tag_name release-v(date +"%Y%m%d%H%M")
    echo $tag_name | pbcopy
    pwd
    git pull
    git push
    git tag $tag_name
    git push --tags
end

# 发版到测试环境
function gdt
    set b_ori (git symbolic-ref --short -q HEAD)
    git checkout dev
    git merge $b_ori -m 'merge'
    git pull
    git push
    git push gh dev
    git checkout -
end

我使用的 fishshell, 再次疯狂安利一波, 几乎零配置, 比 zsh 更高效.

可供参考的教程:

git 的部分稍显啰嗦, 后面的 docker 部分也会有点, 毕竟 git/docker 都是 基础功, 这是没法回避的部分, 后面的实施部分要简单不少, 几张截图就能搞定

docker

一样的风格, 不再赘述 docker 好在哪, 以及 docker 的一些基础概念, 默认你已经了解以下基础知识:

  • docker 的基本概念: 镜像 容器 网络(网络基础/端口映射) 文件挂载 ...
  • docker Dockerfile docker-compose 的基础知识和基本用法

当然, 如果团队有 老司机, 你会发现使用 docker 是一件如此轻松的事, 几乎只是几个命令的事儿.

假设 git 仓库中提供了 docker-compose.yml 文件:

version: '3.1'
services:
    s1: # 定义服务名称
        image: registry.cn-shanghai.aliyuncs.com/daydaygo/dev:hyperf
        volumes: # 挂载代码路径到容器中
            - ../:/data
        ports: # 端口绑定, 如果需要本地个可以访问容器中的服务
            - "80:9501"
        environment: # 设置环境变量
            APP_ENV: dev
        links: # 此服务依赖的其他服务, 按需配置
            - redis
            - mysql
            - rabbitmq       
        tty: true # 设置允许进入容器 tty

那么, 其他开发者日常只需要:

# 定义 alias, 后面省力不少
alias doc='docker-compose

doc up -d s1 # 启动服务(就是 docker 容器), 即由上面的 docker-compose.yml 文件定义的服务
dos stop/restart/rm s1 # 服务管理
doc exec s1 fish # 进入到容器tty, 使用 fishshell(是的, 再次安利 fishshell)

看到这里, 希望你注意到一个更加吃惊的事实:

本地除了 git/docker, 其他什么环境都不需要配置, 容器启动起来后, 项目所需的环境都有了!!!

绑定 aliyun 容器镜像服务(cr)

从这一部分开始, 后面的内容都会比较轻松, 几乎只是几张截图.

  • 使用 aliyun 容器镜像服务, 划重点: 免费.

image

  • 绑定代码源, 推荐 github/gitlab:

image

  • 配置自动构建规则

image

除了默认的 tag 触发的自动构建(这也是上面配置 git tag alias 的原因之一), 我通常会配置 master 分支对应镜像 tag latest, dev 分支对应镜像 tag test, 分别部署到 测试环境/线上环境. 当然, 需要增加其他环境, 再增加一个构建规则就好了.

而我们所需要的代码, 即 Dockerfile, 简单得不好意思贴进来:

  • 项目镜像构建所需的 Dockerfile
# 获取基础镜像
FROM registry.cn-shanghai.aliyuncs.com/daydaygo/dev:hyperf
LABEL maintainer="daydaygo <daydaygo@vip.qq.com>" version="1.0"

# 添加项目源码
COPY . /data
# 设置环境相关配置
COPY .env.prod /data/.env
# 启动服务
ENTRYPOINT ["php", "/data/bin/hyperf.php", "start"]

绑定 aliyun 容器服务swarm(cs)

容器服务其实也是免费的, 收费的部分其实是集群对应的 ecs. 这里啰嗦一些 集群 的概念

  • 集群的逻辑概念: 一个集群中可以有多个应用, 每个应用可能由多个服务协同, 比如上面的 docker-compose.yml 中的 s1 服务, 使用 --links 依赖了 mysql/redis/rabbitmq 3 个服务
  • 集群的物理概念: 一个集群中可以有多台 ecs, 提供相应的 cpu/内存 等计算资源, 这些 ecs 被称之为 节点
  • 集群其他资源: 网络 文件挂载 配置项 ...

使用也很简单, 新建一个集群, 配置好 ecs, 开发测试的话推荐使用 按量付费, 最好至少开 2 台来体验.

  • 好了, 配置我们的第一个应用

image

  • 使用配置文件创建
hyperf-ms: # 定义服务名称
  # 使用容器镜像服务中的镜像
  image: 'registry-vpc.cn-shanghai.aliyuncs.com/daydaygo/hyperf-ms:latest'
  mem_limit: 0
  kernel_memory: 0
  memswap_reservation: 0
  # 容器自动重启
  restart: always
  shm_size: 0
  expose:
    - 9501
  links:
    - rabbitmq
  memswap_limit: 0
  # aliyun 容器服务提供的特殊功能标签
  labels:
    # routing: 简单 http/https 路由, 配置服务的 端口号->域名
    aliyun.routing.port_9501: ms.daydaygo.top
    # scale: 应用数量
    aliyun.scale: '1'
    # log: 关联 aliyun 日志服务, 这里投递容器的 stdout 到日志服务中
    aliyun.log_store_stdout: stdout
    aliyun.log_ttl_stdout: 30
    aliyun.log.timestamp: false
    aliyun.depends: rabbitmq
rabbitmq:
    image: rabbitmq:3.7.8-management-alpine
    hostname: myrabbitmq
    ports:
        - "5672:5672" # mq
        - "15672:15672" # admi
  • 配置触发器, 镜像更新后自动部署

image

  • 也可以在容器镜像服务中配置

image

关联 aliyun 日志服务

关于日志服务, 我之前也啰嗦了不少, 有兴趣可以去看看之前的 blog:

上面配置好 容器服务投递日志到 日志服务 后, 接下来我们还有几步工作要做:

  • 自动创建好的 日志 project, 先修改一下备注

image

  • 对应的 logstore

image

  • 修改 logtail 配置, 推荐使用 json 解析, 几乎零配置

image

  • json 解析, 需要日志输出为 json 格式, 这个也简单, 以 PHPer 使用的 monolog 为例, 只用配置一下 Formatter 就好了:
$app_env = env('APP_ENV', 'dev');
if ($app_env == 'dev') {
    $formatter = [
        'class' => \Monolog\Formatter\LineFormatter::class,
        'constructor' => [
            'format' => "||%datetime%||%channel%||%level_name%||%message%||%context%||%extra%\n",
            'allowInlineLineBreaks' => true,
            'includeStacktraces' => true,
        ],
    ];
} else {
    $formatter = [
        // 看这里
        'class' => \Monolog\Formatter\JsonFormatter::class,
        'constructor' => [],
    ];
}

return [
    'default' => [
        'handler' => [
            'class' => \Monolog\Handler\StreamHandler::class,
            'constructor' => [
                'stream' => 'php://stdout',
                'level' => \Monolog\Logger::INFO,
            ],
        ],
        'formatter' => $formatter,
    ],
];
  • 配置好索引

image

  • 日志服务更多配置

    • 保存快查
    • 配置仪表盘 订阅仪表盘的日报
    • 配置告警 推荐告警到钉钉
一言以蔽之: 日志服务真的是个 宝藏男孩

绑定 Travis CI

CI 的根本在于: 你得有自动化测试才行

PHPer 推荐使用 phpunit, 尤其是微服务化了以后, 服务通常以接口的形式提供, 单测简直不要太好用

说回正题, 来看 Travis CI, 项目中添加一个 .travis.yml 的事儿:

branches:
  only:
  - master
  - dev

language: php

services:
  - docker 

before_install:
  - docker login registry.cn-shanghai.aliyuncs.com -u xxx -p xxx
  - docker build -t ci .
  - docker run -d --name ci ci
  - sleep 5

script:
  - docker exec ci /bin/sh -c "cd /data; phpunit"

notifications:
  email:
    - daydaygo@vip.qq.com
  webhooks:
    - https://oapi.dingtalk.com/robot/send?access_token=xxx

看配置项估计也能看明白:

  • 配置分支触发
  • 根据项目下的 Dockerfile 构建镜像
  • 使用镜像运行容器
  • 执行容器中的 phpunit
  • 通过 email/钉钉 通知 CI 构建信息

写在最后

内容看起来很多, 对参与开发的人而言, 其实很省心:

本地除了安装 git/docker 外, 并不需要其他环境; 除了写代码外, 不需要分心 CI/CD

最后再安利一下使用到的一些工具:

  • git / github / github desktop / gitlab
  • docker / docker-compose
  • fishshell
  • aliyun: 容器镜像服务(cr) 容器服务swarm(cs) 日志服务(sls)
  • 钉钉: 使用钉钉机器人来搜集消息, 当做消息box使用, 上面的所有流程, 都可以配置消息到钉钉
相关实践学习
通过容器镜像仓库与容器服务快速部署spring-hello应用
本教程主要讲述如何将本地Java代码程序上传并在云端以容器化的构建、传输和运行。
Kubernetes极速入门
Kubernetes(K8S)是Google在2014年发布的一个开源项目,用于自动化容器化应用程序的部署、扩展和管理。Kubernetes通常结合docker容器工作,并且整合多个运行着docker容器的主机集群。 本课程从Kubernetes的简介、功能、架构,集群的概念、工具及部署等各个方面进行了详细的讲解及展示,通过对本课程的学习,可以对Kubernetes有一个较为全面的认识,并初步掌握Kubernetes相关的安装部署及使用技巧。本课程由黑马程序员提供。 &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
2月前
|
Kubernetes 持续交付 Docker
探索DevOps实践:利用Docker与Kubernetes实现微服务架构的自动化部署
【10月更文挑战第18天】探索DevOps实践:利用Docker与Kubernetes实现微服务架构的自动化部署
95 2
|
3月前
|
运维 Cloud Native Devops
云原生架构的崛起与实践云原生架构是一种通过容器化、微服务和DevOps等技术手段,帮助应用系统实现敏捷部署、弹性扩展和高效运维的技术理念。本文将探讨云原生的概念、核心技术以及其在企业中的应用实践,揭示云原生如何成为现代软件开发和运营的主流方式。##
云原生架构是现代IT领域的一场革命,它依托于容器化、微服务和DevOps等核心技术,旨在解决传统架构在应对复杂业务需求时的不足。通过采用云原生方法,企业可以实现敏捷部署、弹性扩展和高效运维,从而大幅提升开发效率和系统可靠性。本文详细阐述了云原生的核心概念、主要技术和实际应用案例,并探讨了企业在实施云原生过程中的挑战与解决方案。无论是正在转型的传统企业,还是寻求创新的互联网企业,云原生都提供了一条实现高效能、高灵活性和高可靠性的技术路径。 ##
222 3
|
5月前
|
缓存 Devops 微服务
微服务01好处,随着代码越多耦合度越多,升级维护困难,微服务技术栈,异步通信技术,缓存技术,DevOps技术,搜索技术,单体架构,分布式架构将业务功能进行拆分,部署时费劲,集连失败如何解决
微服务01好处,随着代码越多耦合度越多,升级维护困难,微服务技术栈,异步通信技术,缓存技术,DevOps技术,搜索技术,单体架构,分布式架构将业务功能进行拆分,部署时费劲,集连失败如何解决
|
7月前
|
监控 Devops API
构建高效微服务架构:API网关的作用与实践构建高效稳定的云基础设施:DevOps与容器化技术融合实践
【5月更文挑战第28天】 在当今的软件开发领域,微服务架构因其灵活性、可扩展性和容错能力而备受推崇。本文将深入探讨API网关在构建微服务系统中的关键角色,包括它如何促进系统的高可用性、安全性和性能监控。我们将剖析API网关的核心组件,并借助具体实例展示如何实现一个高效的API网关来服务于复杂的微服务环境。 【5月更文挑战第28天】 随着企业数字化转型的深入,传统的IT运维模式已难以满足快速迭代和持续交付的需求。本文聚焦于如何通过融合DevOps理念与容器化技术来构建一个高效、稳定且可扩展的云基础设施。我们将探讨持续集成/持续部署(CI/CD)流程的优化、基于微服务架构的容器化部署以及自动化监
|
7月前
|
运维 监控 Devops
构建高效稳定的云基础设施:DevOps与自动化运维的融合构建高效微服务架构的最佳实践
【5月更文挑战第28天】 在数字化转型的浪潮中,企业对于云基础设施的依赖日益增加。为了应对不断变化的市场需求和提供不间断的服务,传统的IT运维模式已不再适应现代业务的发展。本文将探讨如何通过结合DevOps理念和自动化工具,实现云基础设施的高效稳定运营。我们将分析自动化运维在提升效率、降低成本以及增强系统稳定性方面的关键作用,并展示实践案例以验证其效果。
|
敏捷开发 运维 监控
【云原生-白皮书】简章2:深入理解DevOps+微服务
在搞懂DevOps和微服务之前,需要先搞懂什么是单体应用/单体架构。简单来说,就跟在校的一些小项目一样,项目的Demo写好了,找一台服务器安装环境,然后把jar包远程上服务器,然后跑起来服务就可以了。
【云原生-白皮书】简章2:深入理解DevOps+微服务
|
7月前
|
Devops jenkins 持续交付
从自建DevOps部署微服务再到云效
以Jenkins+Gitlab基于k8s集群实现自建DevOps系统的方式部署开源微服务PiggyMetrics,与云效DevOps对比,介绍真正的免运维,实现高效的业务开发流程。
421 0
从自建DevOps部署微服务再到云效
|
1月前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
105 6
|
1月前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
39 1
|
7天前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
105 68
从单体到微服务:如何借助 Spring Cloud 实现架构转型