精华内容
下载资源
问答
  • Restful API解释及工作中实践

    万次阅读 2018-06-09 13:59:45
    在工作中,我使用的后台框架是完全遵循Restful API设计的。 遂系统的梳理一遍RESTful API的概念,并且加以工作中的实例,巩固自己的知识,也便于读者更好的理解RESTful API。 什么是RESTful API? 我们可以分为两...

    写在前面

    在工作中,我使用的后台框架是完全遵循Restful API设计的。

    遂系统的梳理一遍RESTful API的概念,并且加以工作中的实例,巩固自己的知识,也便于读者更好的理解RESTful API。

    什么是RESTful API?

    我们可以分为两块来理解,RESTful API = RESTful + API, 也就是基于RESTful的API,那么问题就变成了,什么是RESTful?

    先一言以概之:RESTful是网络接口设计应当遵循的一套规范,这套规范包括了一组架构约束条件和原则。

    REST全称是Representational State Transfer,中文意思是表述性状态转移。通常市面上所说的RESTful API,都是指其风格在HTTP上的应用,但这只是因为目前HTTP是唯一与REST相关的实例。

    RESTful最重要的特征,就是面向资源,通俗一点说,url中只能有名词,动词对应的行为由http方法决定。当然,RESTful还有其他的东西,这个我们之后再看。

    举个例子?

    最近新开发的网页应用,需求是A公司邀请B公司建立合作关系。具体到实现,就是A公司要能够发送邀请,B公司要能够接受邀请。因为这篇文章只讨论API,所以前端实现全部略过。

    假设我已经搭建好了服务器:https://server-address 那么下一步,就是后台实现方法并且暴露给前端调用。

    那我们先实现一个A公司发送邀请的功能吧,未经思考,我们给出答案:https://server-address/createInvitation( id = '001')

    这个uri的意思是,调用createInvitation对应的后台资源,创建一条id='001'的invitation。

    燃鹅,如果我们这样设计,那么我们一下就违背了两条RESTful的规范:

    先说违背了哪两条:

    1. 前面说过,要面向资源,也就是用名词取名

    2. 要用标准的HTTP方法与后台实现对应,createInvitation(id = '001')实际上用的是get方法来传参数,而get方法应该是幂等的,只用来读取资源,标准的方法应该是调用post方法,把id='001'放进HTTP request 的header中去。

    我们给资源的取名是:createInvitation,实际上的主体是动词,可能有同学要说了,我这个是动名词短语做名词呀。那你太秀了,请陈独秀同学坐下来发言。

    不如我们先想想,遵循RESTful的话,应该如何设计创建邀请? 答案是: https://server-address/invitations, 注意我用的是复数形式,不要单复数混用,容易引起麻烦

    答案我知道了,那这样有什么好处呢? 对于invitation这个资源来说,现在只有创建的需求,但是当A公司需要取消,修改时,如果我们用的是createInvitation作为创建的uri,难以避免要新建deleteInvitation,updateInvitation这两个新的uri,而如果采用invitation作为uri,在新建的时候前端用post方法调用https://server-address/invitations, 在取消(删除)invitation时,用delete方法调用,在修改invitation时,用put方法调用。也就是说,所有对invitation的操作,调用的都是https://server-address/invitations这个url,是不是很符合逻辑,也很简洁明了呢?

    我认为RESTful最关键的思维就是上述这个例子了,这是每一个API应该遵守的最佳实践。

    更多:

    RESTful还有其他的比如关于API的版本等等更详细的规范,这些都是按需使用的,具体可以参考:

    RESTful架构详解:http://www.runoob.com/w3cnote/restful-architecture.html

    RESTful API的十个最佳实践:https://www.cnblogs.com/xiaoyaojian/p/4612503.html

    如果对HTTP方法不熟,可以参考:

    http几种请求方法的差别:https://blog.csdn.net/resilient/article/details/52585724

    展开全文
  • 工作中git是一项必不可少的技能,项目的开发进程起着至关重要的作用,下面介绍一些git在工作中的一些使用实践~ 本文介绍了Git是什么、Git的存储结构、Git的提交规则和一些工作中常会用到的git操作的过程,最后...

    工作中git是一项必不可少的技能,在项目的开发进程中起着至关重要的作用,下面介绍一些git在工作中的一些使用实践~

    一:前言

    Git的定义是:分布式版本控制系统,用于项目开发中的版本控制。

    从本质上来讲 Git 是一个内容寻址(content-addressable)文件系统,并在此之上提供了一个版本控制系统的用户界面。

    Git 的核心部分是一个简单的键值对数据库(key-value data store)。 你可以向该数据库插入任意类型的内容,它会返回一个键值,通过该键值可以在任意时刻再次检索(retrieve)该内容。

    git管理的项目工作目录下的每一个文件都不外乎这两种状态:已跟踪或未跟踪。

    • 已跟踪的文件是指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。
    • 工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有放入暂存区。
    • 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。

    Git 保存的不是文件的变化或者差异,而是一系列不同时刻的文件快照。在进行提交操作时,Git 会保存一个提交对象(commit object)。该提交对象会包含一个指向暂存内容快照的指针。 但不仅仅是这样,该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。

    如果转载此博文,请附上本文链接,谢谢合作~ :https://liyangyang.blog.csdn.net/article/details/100939749

    如果感觉这篇文章对您有所帮助,请点击一下“喜欢”或者“关注”博主,您的喜欢和关注将是我前进的最大动力!

    微信扫下述二维码关注公众号,回复“源码”,即可免费获取“经典飞机大战源码 + 经典像素鸟游戏源码 + 人事管理系统源码 ”!
    匠心Java*

    二:git存储

    git将项目的存储分为4部分,每部分有自己作用,见下图:(图片来自:博客)
    在这里插入图片描述

    • Workspace:工作区(当前用户操作修改的区域)
    • Index / Stage:暂存区 (add后的区域)
    • Repository:仓库区或本地仓库(commit后的区域)
    • Remote:远程仓库(push后的区域)

    整体过程可以简述为:

    • 工作区–>add–>暂存区–>commit–>本地仓库区–>push–>远程仓库区
    • 远程仓库区–>fetch–>使用refs\remotes下对应分支文件记录远程分支末端commit_id 和 本地仓库区 -->merge–>工作区
    • 远程仓库区–>pull–>使用refs\remotes下对应分支文件记录远程分支末端commit_id and 本地仓库区 and 工作区

    git pull和git fetch有什么不同呢?下面简单说一下

    想要知道他们得不同,我们需要先了解两个概念

    • FETCH_HEAD:可以看做是一个版本链接,记录在本地的refs\remotes下对应分支文件中,指向着目前已经从远程仓库取下来的分支的最新版本的commit_id。
    • commit-id:在每次本地commit来保存当前工作到本地仓库区后, 会产生一个commit-id,这是一个能唯一标识一个版本的序列号。 在使用git push后,这个序列号还会同步到远程仓库。

    所以他们之间的不同在于:

    • git pull 直接将远程分支的修改更新到本地仓库区和本地工作区,我们就可以在本地工作区中看到最新代码
    • git fetch 只将远程分支的修改拉取到本地仓库,并更新到FETCH_HEAD,记录远程分支最新的commit_id,不会更新本地工作区代码,只有使用了git merge 才会将提交更新到本地仓库区和工作区

    其他想要了解更多git内部消息请移步我的另一篇博文:git内部存储实现机制

    git status中的体现,见下图:
    在这里插入图片描述

    • Changes to be committed::代表被add的文件,被加载到了暂存区
    • Changes not staged for commit:代表在当前分支中被修改的文件,还没有被add,存储在工作区
    • Untracked files :代表不被git追踪的文件,可以理解为不被git管理的文件
    • 如果没有Changes to be committed和Changes not staged for commit说明现阶段所有的修改已经被commit到本地仓库
    • 如果git status后出现下述情况,说明还有已经的commit到本地仓库的还未被push到远程仓库
    $ git status
    On branch master
    Your branch is ahead of 'origin/master' by 2 commits.
      (use "git push" to publish your local commits)
    

    Git 作为一个系统,是以它的一般操作来管理并操纵(HEAD、index、Working Directory)三棵树的

    • HEAD: 是当前分支引用的指针,它总是指向该分支上的最后一次提交。 这表示 HEAD 将是下一次提交的父结点。 通常,理解 HEAD 的最简方式,就是将它看做 你的上一次提交的快照。
    • index: index索引是你的 预期的下一次提交。 我们也会将这个概念引用为 Git 的 “暂存区域”,这就是当你运行 git commit 时 Git 看起来的样子。Git 将上一次检出到工作目录中的所有文件填充到索引区,它们看起来就像最初被检出时的样子。 之后你会将其中一些文件替换为新版本,接着通过 git commit 将它们转换为树来用作新的提交。
    • Working Directory:最后,你就有了自己的工作目录。 另外两棵树以一种高效但并不直观的方式,将它们的内容存储在 .git 文件夹中。 工作目录会将它们解包为实际的文件以便编辑。
      在这里插入图片描述

    三:git提交规则

    首先,有个问题需要确认一下,提交信息是使用中文还是英文呢?

    如果你的项目是开源项目并且面向国际的开源项目,类似于阿里的Druid\PingCAP的TiDB等,那么一定要是用英文提交信息的!
    如果你的项目是公司内部使用或者只会被公司内部开发修改,那么中文也是不错的,更加便于查看和管理。当然,开发组中的英文能力都不错的话,用英文也是可以的。

    分支Branch管理:
    如果没有一个好的branch管理的话,可能会有下述图的情况,刺不刺激~
    在这里插入图片描述
    推荐的分支管理:

    • master 分支为主分支(保护分支),禁止直接在master上进行修改代码和提交,此分支的代码可以随时被发布到线上;
    • develop 分支为测试分支或者叫做合并分支,所有开发完成需要提交测试的功能合并到该分支,该分支包含最新的更改;
    • feature 分支为开发分支,大家根据不同需求创建独立的功能分支,开发完成后合并到develop分支;
    • fix 分支为bug修复分支,需要根据实际情况对已发布的版本进行漏洞修复;

    标签Tag管理:
    Tag采用三段式:v版本.里程碑.序号(v2.3.1)

    • 架构升级或架构重大调整,修改第1位
    • 新功能上线或者模块大的调整,修改第2位
    • bug修复上线,修改第3位

    当然,可以根据实际情况来设计,比如项目特别大,可以使用四段表达Tag,项目比较小也可以使用二段式Tag,只要符合场景并有实际意义即可
    Tag相关:Tag管理

    提交信息格式:
    下面只是提供一种建议格式,大家可以根据自己的项目实际情况来定格式,只要能把当前提交表达清楚,格式统一,方便快速阅读和定位即可!

    • 建议中文示例:

      • <新功能>(urllAnalyz) 添加解析url功能l
      • <修改>(TestServiceImpl) 修改某功能的某个实现为另一个实现
      • <Bug修复>(TestUnti) 修复url特殊情况下解析失败问题 (issue#12)
      • <重构>(getData) 重构获取数据的方法
      • <测试>(getDataTest) 添加(修改、删除)获取数据的单元测试代码
      • <文档>(doc)修改(添加、删除)文档
    • 对应到英文:

      • feat:新功能(feature)
      • style: 格式
      • fix:修补bug
      • refactor:重构
      • test:测试相关
      • docs:文档(documentation)
    • 格式(type:scope:body:issue)
      <|新功能|修改|Bug修复|重构|测试>(影响模块)提交描述信息(#issue?)

    • 优点作用

      • 与github数据issue关联,便于通过issue获取更多信息
      • commit 提交时,格式统一,便于后续快速准确定位提交
      • 可以更好的将此次提交表述清楚

    四:Git操作过程

    初始化项目,并上传到git服务器

    基本过程: 创建远程仓库、初始化本地git仓库、将本地仓库与远程仓库关联起来、添加本地仓库想要提交的代码到本地git缓冲区,将本地仓库的本地分支与远程仓库的远程分支关联起来、提交代码

    1. 在git服务器上创建同名git项目,并获取http地址

    2. 本地git初始化项目git仓库,在项目目录下
      git init

    3. 将本地git仓库和远程仓库关联起来,并设置远程仓库名称
      git remote add <name> <http地址>

    其中http地址为上述第一步获取的远程仓库的地址,name一般为origin,当然也可以设置其他的名字
    例如:git remote add origin http://igit.corp.com/my/test.git

    1. 添加项目文件到本地git缓冲区
      git add -A
      git commit -m ‘初始化项目’
      或者
      git commit -a -m ‘初始化项目’

    2. 将本地分支关联远程分支并提交,git默认在远程分支上创建于本地分支同名的分支
      git push --set-upstream origin master

    这就是将本地的master分支 与 origin远程仓库关联起来并在远程仓库创建同名master分支,以后本地master都提交到远程仓库中的origin/master分支上。
    upstream:上游的意思

    1. 至此,应该就可以了,我们可以在git服务器上刷新看看是否提交上去了

    提交某一分支的修改

    1. 查看当前分支的修改
      git status
    2. 查看想要查看的文件的修改
      git diff <file_name>
    3. 确认正确后,提交修改到暂存区
      git add -A 或者 git add <file_name> <file_name>
    4. 提交到本地仓库
      git commit -m '提交信息'
    5. 提交到远程仓库
      git push

    拉取远程分支修改到本地分支

    当远程分支别人推了一版新的代码时,我们想要将代码拉下来,可以采用两种方式pull 和 fetch+merge:(他们的不同点文章上面已经解释)

    使用pull:

    1. 将远程分支最新代码更新合并到本地仓库区和工作区
      git pull

    使用fetch:

    1. 将远程所有分支最新的commit_id更新到FETCH_HEAD,记录远程分支最新的commit_id 和 本地仓库区
      git fetch
    2. 将最新的代码合并到工作区
      git merge

    取消track某一文件

    1. git rm -r --cache <file_name>

    untrack后,使用commit -a 时,不会将其添加到暂存区中

    1. 之后会在.ignore文件中将该untrack的文件添加进去,完成

    保存账号密码,避免每次push都要输入(简单方法)

    1. 确保在git中手动输入过账号和密码
    2. 输入下面语句即可
      git config --global credential.helper store

    暂存自己的修改,便于接着工作(特别有用)

    如果你正在一个分支上工作修改,leader让你改另外的分支的BUG或者对其他的分支做一些操作。
    我们知道如果一个分支上有还没有commit的修改的话,不可以切换分支,但是又因为自己的工作还未完成,不想commit,此时git stash 就起作用了。
    你要把现在正在工作的分支保存下来,等处理完其他的再回来接着当前分支的修改工作。

    1. 将当前分支的修改暂存起来(此处不等于add+commit)
      git stash

    备份当前的工作区的内容,从最新的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。
    同时,将当前的工作区修改的内容保存到Git栈中暂存起来。

    1. 切换到别的分支工作,完成后切换回原来的工作分支,查看暂存列表
      git stash list

    显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复

    1. 恢复暂存的修改到工作区
      git stash apply <stash_name> 恢复暂存之后不删除暂存

    从Git栈中读取最新一次保存的内容,恢复工作区的相关内容。

    git stash pop 恢复暂存之后删除暂存

    从Git栈中读取最新一次保存的内容,恢复工作区的相关内容。之后pop会删除最新的暂存。

    1. 删除“暂存”
      git stash drop <stash_name>

    从Git栈删除最旧的一个暂存

    1. 结束

    将文件修改回退到某一状态
    一些已经提交的或者已经修改的部分,想要再修改一下,或者删除已经提交的

    1. 删除某些commit,将head重定位到某一commit(回溯到以前的版本)
      git reset --hard <commit_id> 注意!!! 此步骤会将commit_id前的所有commit修改删除
      或者 git reset <commit_id> 此步骤不会将commit_id前的commit删除,而是会将修改回退到本地工作区
      git push origin HEAD --force 此步骤将服务器方也设置为相commit

    2. 将文件修改恢复到当前已提交分支的原样(未 git add 情况下)
      撤销修改就回到和版本库一模一样的状态,即用版本库里的版本替换工作区的版本
      git checkout -- <file_name>

    3. 将文件修改恢复到当前已提交分支的原样(已经 git add 情况下)
      git reset HEAD 将add退回
      git checkout -- <file_name>

    4. 将文件修改恢复到已提交分支的原样(已经 git commit 情况下)
      git reset <commit_id> 此处commit_id可以是任意分支的commit_id
      git checkout -- <file_name>

    版本的回溯与前进
    有时候需要回溯或前进到以前的版本 或 回溯前进到以前的commit

    只要记住commit_id就可以在版本之间来回的穿梭,注意是可以“来回”穿梭哦

    1. 获取需要回溯到版本的commit_id
      git log --> 复制所需的版本commit_id
    2. 回退到该版本
      git reset --hard <commit_id>
    3. 如果想让服务器也回退到该版本的话
      git push origin HEAD --force

    五:Git常用命令

    初始化项目为git项目
    git init

    clone服务器代码到本地
    git clone <http_url>

    添加修改文件到暂存区
    git add <file_name>
    git add -A 添加所有修改文件到暂存区

    提交修改到本地仓库
    git commit -m '提交信息'
    git commit -a -m '提交信息' 相当于git add -A + git commit -m 的整合

    提交本地仓库的修改到远程仓库
    git push

    将远程库<remote_name>的远程分支<branch_name>作为当前分支的上游分支
    git push --set-upstream <remote_name> <branch_name>
    <remote_name>为远程仓库的别名,一般为origin

    查看文件本次的修改
    git diff 显示本次所有被修改文件的修改
    git diff <file_name> 显示该文件本次的修改

    查看当前分支下当前状态
    git status 显示出被修改的文件和提交的次数等

    查看提交历史
    git log
    git log --graph 查看分支合并图

    merge其他分支到当前分支
    git merge <branch_name>

    在merge过程如果出现冲突,在解决冲突后会产生一个新的commit,并且HEAD指向该commit
    如果没有冲突,HEAD会在分支的最新commit上

    切换到上一个分支
    git checkout -

    切换到其他分支
    git checkout <branch_name>

    在某一分支基础上创建新分支
    git checkout <branch_name> 切换到基础分支
    git checkout -b <new_branch_name> 在当前分支基础上 创建新分支

    显示分支
    git branch 所有本地分支
    git branch -r 所有远程分支
    git branch -a 所有分支,本地和远程

    删除本地分支
    git branch -D <branch-name>

    删除远程分支
    git push origin --delete <branch-name>

    添加一个新的远程仓库
    git remote add <shortname> <url>

    在同一个项目的git url中可以添加多个远程仓库
    每个仓库相互隔离有自己的分支管理

    将本地分支与远程仓库中分支联系起来
    git push --set-upstream <远程仓库名称> <远程仓库中分支名称>

    以后本地的该分支的push,会默认提交到设置的远程仓库中远程分支中

    删除远程仓库
    git remote rm <远程仓库name>

    删除本地tag
    git tag -d <tag_name>

    删除远程tag
    git push origin :refs/tags/<tag_name>

    查看tag信息
    git show <tag_name>

    暂存当前修改
    git stash

    查看暂存列表
    git stash lsit

    恢复暂存的修改
    git stash apply (恢复后不删除暂存)
    git stash pop (恢复后删除暂存)

    删除暂存
    git stash drop

    撤回已经add到暂存区的文件到本地工作区
    git reset HEAD <file_name>
    git reset HEAD 回退所有add

    add会被标识为Changes to be committed,取消add后标识为Changes not staged for commit(不等于untrack)

    取消track某一文件
    git rm -r --cache <file_name>

    untrack后,使用commit -a 时,不会将其添加到暂存区中

    只merge某一个分支上的某一个commit
    git cherry-pick <被merge分支中的某一个commit的commit-id>

    撤销在本地工作区的文件的修改
    撤销修改就回到和版本库一模一样的状态,即用版本库里的版本替换工作区的版本
    git checkout -- <file_name>

    删除某些commit,将head重定位到某一commit(回溯到以前的版本)
    git reset --hard <commit_id>
    git push origin HEAD --force 此步骤将服务器方也设置为相commit

    删除本地在远程服务器上不存在的分支
    git remote prune origin

    拉取远程分支到本地
    git fetch origin <branch_name>

    新建一个tag到指定commit
    git tag <tag_name> <commit_id>
    git tag <tag_name> 当前commit

    取消当前合并,重建合并前状态
    git merge --abort

    总结

    本文介绍了Git是什么、Git的存储结构、Git的提交规则和一些工作中常会用到的git操作的过程,最后总结了常用的命令。Git在工作中的团队开发中起着至关重要的作用,希望本篇文章可以对大家有些许帮助~

    推荐阅读:
    shell-【技术干货】编写shell脚本所需的语法和示例
    Git - 使用git不知道内部实现机制怎么行

    参考:博客 博客 git官网

    如果转载此博文,请附上本文链接,谢谢合作~ :https://liyangyang.blog.csdn.net/article/details/100939749

    如果感觉这篇文章对您有所帮助,请点击一下“喜欢”或者“关注”博主,您的喜欢和关注将是我前进的最大动力!

    展开全文
  • 浏览器工作原理和实践

    千次阅读 2019-08-31 18:18:51
    参透了浏览器的工作原理,可解决80%的前端难题. 帮助开发web前端项目. 3.学习 课程目录 开篇词 (1讲) 开篇词 | 参透了浏览器的工作原理,你就能解决80%的前端难题 宏观视角...

    1.介绍

    见正文3

    2.应用背景

    参透了浏览器的工作原理,可解决80%的前端难题.

    帮助高效快速安全开发web前端项目.

    3.学习

     

     

    课程目录

    开篇词 (1讲)

     

    开篇词 | 参透了浏览器的工作原理,你就能解决80%的前端难题

     

    宏观视角下的浏览器 (6讲)

    01 | Chrome架构:仅仅打开了1个页面,为什么有4个进程?

    02 | TCP协议:如何保证页面文件能被完整送达浏览器?

    03 | HTTP请求流程:为什么很多站点第二次打开速度会很快?

    04 | 导航流程:从输入URL到页面展示,这中间发生了什么?

    05 | 渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的?

    06 | 渲染流程(下):HTML、CSS和JavaScript,是如何变成页面的?

     

    浏览器中的JavaScript执行机制 (5讲)

    07 | 变量提升:JavaScript代码是按顺序执行的吗?

    08 | 调用栈:为什么JavaScript代码会出现栈溢出?

    09 | 块级作用域:var缺陷以及为什么要引入let和const?

    10 | 作用域链和闭包 :代码中出现相同的变量,JavaScript引擎是如何选择的?

    11 | this:从JavaScript执行上下文的视角讲清楚this

     

    V8工作原理 (3讲)

    12 | 栈空间和堆空间:数据是如何存储的?

    13 | 垃圾回收:垃圾数据是如何自动回收的?

    14 | 编译器和解释器:V8是如何执行一段JavaScript代码的?

     

    浏览器中的页面循环系统 (6讲)

    15 | 消息队列和事件循环:页面是怎么“活”起来的?

    16 | WebAPI:setTimeout是如何实现的?

    17 | WebAPI:XMLHttpRequest是怎么实现的?

    18 | 宏任务和微任务:不是所有任务都是一个待遇

    19 | Promise:使用Promise,告别回调函数

    20 | async/await:使用同步的方式去写异步代码

     

    浏览器中的页面 (8讲)

    21 | Chrome开发者工具:利用网络面板做性能分析

    22 | DOM树:JavaScript是如何影响DOM树构建的?

    23 | 渲染流水线:CSS如何影响首次加载时的白屏时间?

    24 | 分层和合成机制:为什么CSS动画比JavaScript高效?

    25 | 页面性能:如何系统地优化页面?

    26 | 虚拟DOM:虚拟DOM和实际的DOM有何不同?

    27 | 渐进式网页应用(PWA):它究竟解决了Web应用的哪些问题?

    28 | WebComponent:像搭积木一样构建Web应用

     

    浏览器中的网络 (3讲)

    29 | HTTP/1:HTTP性能优化

    30|HTTP/2:如何提升网络速度?

    31|HTTP/3:甩掉TCP、TLS 的包袱,构建高效网络

     

    浏览器安全 (5讲)

    32 | 同源策略:为什么XMLHttpRequest不能跨域请求资源?

    33 | 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?

    34 | CSRF攻击:陌生链接不要随便点

    35 | 安全沙箱:页面和系统之间的隔离墙

    36 | HTTPS:让数据传输更安全

     

     

    该专栏已经学习了两遍, 挺好的,  感觉还需要后续学习第三遍, 并结合其他资料, 以及前端项目一起学习消化, 融化贯通    ///  20210305 12:20 周五 家里

     

    4.问题/补充

    Note:

    含记名不记名网友问题

     

    4.1 回顾浏览器的进化路线,你认为推动浏览器发展的主要动力是什么?

    [一个角度来说,最大动力就是chrome的出现。曾经的IE像极了诺基亚,chrome就像是横空出世的iPhone ,当着IE的面告诉IE,浏览器应该这么玩儿。
    另一个角度也是互联网的发展需要,人们所需要的不再是只是简单展示个页面的浏览器,需要有复杂的交互,浏览器应该能做更多的事情,这对浏览器的稳定性、以及性能都有了新的要求。所以出来一个性能符合要求的浏览器也是必须的。
    还有就是11年后相对规范的es5的出现,再之后es6.7,web能做的事情越来越多了,web工程化,再后来node的出现,前端体系越来越庞大]

     

    07 | 变量提升:JavaScript代码是按顺序执行的吗?

    1.老师好,请教您一个问题。

    debugger;
    (function(){
        console.log(g)
        if(true){
            console.log('hello world');
            function g(){ return true; }
        }
    })();

    这个函数步进调试时,发现打印g时值是undefined而不是提示not defined,说明if中g函数确实是提升了,但是为何不是g()而是undefined?然后走完function g(){ return true; }这一步后 console.log(g)中的g才变为g()。这里条件声明函数的变量提升有点搞不明白。
    作者回复: 

    ES规定函数只不能在块级作用域中声明,

    function foo(){
        if(true){
            console.log(&#39;hello world&#39;);
            function g(){ return true; }
        }
    }

    也就是说,上面这行代码执行会报错,但是个大浏览器都没有遵守这个标准。

    接下来到了ES6了,ES6明确支持块级作用域,ES6规定块级作用域内部声明的函数,和通过let声明变量的行为类似。

    规定的是理想的,但是还要照顾实现,要是完全按照let的方式来修订,会影响到以前老的代码,所以为了向下兼容,个大浏览器基本是按照下面的方式来实现的:

    function foo(){
        if(true){
            console.log(&#39;hello world&#39;);
            var g = function(){return true;} 
        }
    }

    这就解释了你的疑问,不过还是不建议在块级作用域中定义函数,很多时候,简单的才是最好的。

     

     

    2. ES6 在附录B里面规定:

    1.允许在块级作用域内声明函数。
    2.函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
    3.同时,函数声明还会提升到所在的块级作用域的头部。

    这里的表现应该是这样:
    function foo(){
        var g1;
        if(true){
            function g2(){return true;}
            console.log(&#39;hello world&#39;);
            g1 = g2;
        }
    }

    g1和g2表示引用不一样,这里是同名关系,但是所在的变量作用域是不一样的。

    下面这个文章详细解释了。
    https://juejin.im/post/5eaa8211e51d454de64e388e
     

    3. 老师,可以请教下吗,在编译完成之后是单单生成了字节码,再到执行过程中变成对应平台的机器码? 还是编译过程已经生成了对应平台的机器码, 执行阶段就直接去执行相应的机器码?
    作者回复: 先是生成字节码,然后解释器可以直接执行字节码,输出结果。 但是通常Javascript还有个编译器,会把那些频繁执行的字节码编译为二进制,这样那些经常被运行的函数就可以快速执行了,通常又把这种解释器和编译器混合使用的技术称为JIT

     

     

     

    ...

    5.推荐书籍

    TBD

    6..参考

    极客时间专栏:浏览器工作原理和实践 --李兵 以及不记名网友的评论见解

    后续补充

    ... 

    展开全文
  • DevOps 公司项目实践落地

    万次阅读 2017-10-17 17:47:46
    DevOps方案实施互联网行业已经相对成熟了,而游戏行业还处在起步的初级阶段(据个人了解的身边游戏公司情况),而自己又对DevOps有一定的研究与实践,也想本着学以致用的思想,结合了公司游戏类型和业务方向...

    GitChat 作者:杨彪
    原文:DevOps 在公司项目中的实践落地
    关注微信公众号:「GitChat 技术杂谈」 一本正经的讲技术

    【不要错过文末彩蛋】

    前言

    DevOps方案实施在互联网行业中已经相对成熟了,而在游戏行业中还处在起步的初级阶段(据个人了解的身边游戏公司情况),而自己又对DevOps有一定的研究与实践,也想本着学以致用的思想,结合了公司游戏类型和业务方向摸索了一套游戏行业的DevOps实施落地方案。该方案不一定是很好的,不过它帮助我们提高了开发的效率和规范了流程,减少了人为的失误率和事故率。

    前阵子受「中国持续交付大会」主办方的邀请,有幸能在ThoughtWorks办公室与各行业DevOps精英们一起探讨“DevOps在游戏中的具体实现”,发张当时活动的照片看看现场有多火爆。

    DevOps游戏中的实践

    DevOps游戏中的实践

    现场还抽奖赠送了我和朋友合著的《分布式服务架构:原理、设计与实战》新书,感兴趣的可以扫描二维码购买哦(一不小心打了个广告嘿嘿)。

    《分布式服务架构:原理、设计与实战》

    接下来我将从“DevOps理念”、“DevOps技术栈”和“游戏系统架构”三个方面具体分析如何进行游戏的DevOps实践落地。

    DevOps理念

    DevOps究竟是什么

    DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。——维基百科

    DevOps是一种文化转变,或者说是一个鼓励更好地交流和协作(即团队合作)以便于更快地构建可靠性更高、质量更好的软件的运动。——Mike Kavis

    Mike Kavis是美国Cloud Technology Partners公司的副总裁兼首席架构师,他也更加详细地描述介绍说:DevOps是软件开发生命周期(SDLC)从瀑布式到敏捷再到精益的发展。DevOps超越了敏捷,它的关注点是从SDLC中移除浪费。通常情况下,发现浪费或者瓶颈的形式包括:不一致的环境,人工的构建和部署流程,差的质量和测试实践,IT部门之间缺少沟通和理解,频繁的中断和失败的协定以及那些需要珍贵的资源、花费重要的时间和金钱才能保持系统运行的全套问题。

    他还看到另一个重复浪费是:一个DevOps团队的第一步通常是决定他们是否应该使用Chef或者Puppet(或者是Salt、Ansible等其他任何热门的东西)。他们甚至还没有定义自己打算解决的问题,即使他们手头的工具可以解决它们。这些团队通常会紧张地构建数千行脚本,但是这就产生了一个问题:“我们的职责是编写Chef脚本还是通过质量更好、更稳定的产品更快地进入市场?”。在大多数情况下,这些团队会将自己逼入绝境,大量的专有脚本实际上是增加了系统的浪费,而隐藏在DevOps运动之后的驱动力是从系统中移除浪费,这些团队并没有做到这一点。Mike Kavis原文

    而目前对 DevOps 有太多的说法和定义,不过它们都有一个共同的思想:“解决开发者与运维者之间曾经不可逾越的鸿沟,增强开发者与运维者之间的沟通和交流”。而我个人认为,DevOps 可以用一个公式表达:

    文化观念的改变 + 自动化工具 = 不断适应快速变化的市场

    其核心价值在于以下两点:

    1. 更快速地交付, 响应市场的变化。

    2. 更多地关注业务的改进与提升。

    当理解了什么是DevOps后,那我们为什么需要它呢?它给我们又带来了哪些好处?

    为什么需要DevOps

    当今世界改变的速度已与过去不同,而每当经历一个颠覆性的技术革命时,都给这个世界带来了深刻的变化,大数据、云计算、人工智能、VR/AR和区块链等新兴技术推动着世界不断变化,如何应对这样一个VUCA时代,让我们能够在环境变化的时候快速响应呢?

    VUCA时代

    V=Volatillity(易变性)是变化的本质和动力,也是由变化驱使和催化产生的

    U=Uncertainty(不确定性)缺少预见性,缺乏对意外的预期和对事情的理解和意识

    C=Complexity(复杂性)企业为各种力量,各种因素,各种事情所困扰。

    A=Ambiguity(模糊性)对现实的模糊,是误解的根源,各种条件和因果关系的混杂。

    接下来我将从“产品迭代”和“技术革新”两个层面分析介绍如何变化的。

    产品迭代

    我们不管是做互联网还是做游戏,其实最终都是在做产品,做一款用户喜欢的产品。乔布斯有句非常著名的名言:“消费者并不知道自己需要什么,直到我们拿出自己的产品,他们才发现,这是我想要的东西”。所以乔帮主能够在一开始的时候就设计好了产品最终的效果,然后按照零部件一步步迭代生产,其步骤可以用下图所示:

    乔布斯模式

    全世界只有一个乔布斯,而在我们现实的产品迭代中却是这样的,对话如下:

    用户:我平时上下班都是走路,每天都要走五公里,好辛苦,有没有办法帮我设计个工具,解决下我的痛点。

    我们思考了下,觉得这个不是很难嘛,可以试下,于是我们讨论 -> 设计 -> 开发 -> 测试 -> 交付给用户了一个滑板

    用户:这个滑板不好操控,可以给我加个扶手吗?

    然后我们按照用户新的需求,生产了个滑板车

    用户:滑板车得滑着走,能不能让我可以骑着走的。

    我们继续改进产品,生产了个自行车

    用户:自行车还得登着走,路程远了也很累。

    我们又继续优化,把它变成了电瓶车

    用户:电瓶车倒是解决了的需求,不过就是不太安全,能再优化下产品吗?

    经过各种努力我们最后生产出了一辆漂亮的小轿车交付给了用户,终于让用户满意了。

    DevOps模式

    现实中的用户其实一开始并不知道自己想要什么,但是直到看到了我们的产品,他才知道自己不想要什么。

    即让现实的产品迭代是如此曲折和反复的,那我们有没有办法快速交付价值、灵活响应变化呢?答案就是DevOps,它是面向业务目标,助力业务成功的最佳实践。

    产品的迭代需要DevOps,那么技术的革新更加促进了DevOps的快速发展和落地实施,下面让我们一起看一下技术又是如何支持产品的迭代而不断革新地呢?

    技术革新

    在以前的系统中业务单一、逻辑简单、用户量少,项目团队的规模一般在 10~30人。而现在的系统要面对不同用户的定制化推荐等,互联网连接着人与人、人与物、以及物与物,业务也变得越来越复杂,功能越来越多,如果整个系统耦合在一起,则必定会牵一发而动全身,导致系统维护起来相当困难。

    因此IT技术架构也随着系统的复杂化而不断地变化革新,从早期所有服务的All In One发展到现在的微服务架构、从纯手动操作到全自动化流程、从单台物理机到云平台,下图展示了IT技术革新的变化:

    技术革新

    现在DevOps已经成为发展的趋势了,那它又是怎么实现落地的呢?

    如何实现DevOps的落地

    知之真切笃实处即是行,行之明觉精察处即是知 —— 明•王守仁《传习录》

    在些我引用了圣贤王阳明的一句名言,他提倡“知行合一”,通俗的讲就是做事情要理论与实践相结合。我们在实现DevOps落地时也一定要遵循“理论与实践相结合”的方式进行,理论就是我们做事的指导思想,而实践就是具体做事的方法,接下来我就从我在公司中是如何按照理论与实践相结合来推动DevOps落实地。

    落实DevOps的指导思想

    首先我们还是要回到什么是DevOps,如果大家忘记了可以回到之前再温故一下,包括我总结的DevOps公式。

    其实DevOps核心思想就是:“快速交付价值,灵活响应变化”。其基本原则如下:

    • 高效的协作和沟通;

    • 自动化流程和工具;

    • 快速敏捷的开发;

    • 持续交付和部署;

    • 不断学习和创新。

    DevOps核心功能

    然而这些基本原则又是如何与项目研发息息相关的呢,也就是它们在我们的开发过程中的各个环节是如何体现的?请看下面一张来自《success with enterprise dev-ops - whitepaper》的介绍图:

    DevOps主要知识体系

    • 敏捷管理:一支训练有素的敏捷开发团队是成功实施DevOps的关键。

      根据康威定律:软件团队开发的产品是对公司组织架构的反映

      所以根据公司情况调整组织结构是首要条件,它将直接影响到需求、设计和开发阶段的效率、以及沟通的成本。

      关于团队的沟通成本在《人月神话》中有个很好的计算公式:沟通成本 = n(n-1)/2,其中n为人数,所以沟通成本将随着组织人员的增加而呈指数级增长。而小而快的敏捷团队如何划分,我将在后面“DevOps的具体实施方法”一节中详细介绍。

    • 持续交付部署:实现应用程序的自动化构建、部署、测试和发布。

      通过技术工具,把传统的手工操作转变为自动化流程,这不仅有利于提高产品开发、运维部署的效率,还将减少人为因素引起的失误和事故,提早发现问题并及时地解决问题,这样也保证了产品的质量。下图展示了DevOps自动化的流程:

      DevOps自动化流程

      此图来自我的新书《分布式服务架构:原理、设计与实战》,书中也有具体介绍持续交付部署的细节内容。

    • IT服务管理:可持续的、高可用的IT服务是保障业务正常的关键要素,它与业务是一个整体。

      IT服务管理(ITSM)直接影响产品运营的整个生命周期,传统的IT服务管理(像ITIL)在生产中做的非常好了,但是它对于DevOps来说又显得过于繁琐,所以有必要为DevOps创建一个只关注业务持续性的ITMS,它只需要很少的必要资源来为相应的业务提供服务,ITMS更多地从业务角度考虑了。

      注:白话解释下什么是IT服务管理(ITSM),它是传统的“IT管理”转向为“IT服务”为主的一种模式,前者可能更关注具体服务器管理、网络管理和系统软件安装部署等工作;而后者更关注流程的规范化、标准化,明确定义各个流程的目标和范围、成本和效益、运营步骤、关键成功因素和绩效指标、有关人员的责权利,以及各个流程之间的关系等,比如建立线上事故解决流程、服务配置管理流程等;
      而光有流程还不够,因为流程主要是IT服务提供方内部使用的,客户对他们并不感兴趣,所以还需将这些流程按需打包成特定的IT服务,然后提供给客户使用,比如在云平台上购买一台虚拟云主机一样。

    • 精益管理:建立一个流水线式的IT服务链,打通开发与运维的鸿沟,实现开发运维一体化的敏捷模式。

      精益生产主要来源于丰田生产方式 (TPS)的生产哲学,它以降低浪费、提升整体客户价值而闻名,它主要利用优化自动化流程来提高生产率、降低浪费。所以精益生产的精髓是即时制(JIT)和自动化(Jidoka)。

      JIT(Just In time):JIT用一句话描述就是消耗最少的必要资源,以正确的数量,生产和运送正确的零件。在这种模式下工作,可以最大程度上降低库存,防止过早或者过度生产。大多数公司更倾向用库存来避免潜在的停线风险,而丰田却反其道而行之。通过减少库存“逼迫”对生产中产生的问题做及时且有效的反应。当然JIT这一模式对解决问题的能力是相当大的考验,在能力不足的情况下,会有相当大的断线风险。

      Jidoka(Build in quality):自动化,日语表示为“自働化”,字面含义是自动化,日语里表示为“自動化”,而在丰田TPS系统里,特意给“動”字加上了“人”字旁变成了“働”,换句话说,TPS/精益生产渴望生产的过程控制能像“人”一样智能,在第一时间就异常情况下自动关闭。这种自动停机功能可以防止坏件流入下游,防止机器在错误的生产状态下造成损坏,也可以让人更好的在当前错误状态下进行故障分析。当设备能够做到自动分析故障时,就可以将监管机器的“人”真正解放出来,做到对人力成本的节省。
      ——来自知乎

    下图展示了丰田TPS(Toyota Production System)手册中的精益小屋:

    TPS House

    而精益软件开发是精益生产和实践在软件开发领域的应用,总结为如下七条原则:

    1. 消除浪费

    2. 增强学习

    3. 尽量延迟决定

    4. 尽快发布

    5. 下放权力

    6. 嵌入质量

    7. 全局优化

    精益管理贯穿于整个DevOps阶段,它鼓励主动发现问题,不断的优化流程,从而达到持续交付、快速反馈、降低风险和保障质量的目的。接下来让我们看看DevOps具体的实现方法。

    实施DevOps的具体方法

    • 建立快速敏捷团队

      根据之前介绍的康威定律,我们可以看下目前公司中的项目团队结构是怎么的,如下图所示:

      传统的组织结构和系统架构

      我相信这不仅仅是我们公司这样的结构,而是目前大多数IT互联网公司普遍的分层结构吧,它们一般分为七大部门:产品策划、设计美术、前端工程师、后端工程师、测试工程师、运维&DBA和市场运营等。各部门之间天然的形成了沟通障碍墙,相互之间主要以邮件和会议的形式沟通,效率低下、需求变更困难、很难快速响应市场变化和持续交付高品质的产品。

    那么如何调整组织结构,建立一个Scrum团队呢?(什么是Scrum请参考维基百科

    我们会按照业务功能划分团队,建立沟通群组,设置产品负责人(一个策划人员)、Scrum Master(我们一般选择测试人员担任,测试驱动开发模式)和开发者团队(前端工程师、后端工程师、测试各一名),最后的组织结构和系统架构如下图所示:

    Scrum团队和系统架构

    一个高效的敏捷团队是DevOps能落地的保障,那么自动化流程就是保证产品快速交付和持续部署的有效机制,接下来为大家介绍我们是如何实现自动化流程的?

    • 实现自动化的流程

      直接看图说话吧,以下为一个完整DevOps的Pipeline:

      DevOps Pipeline

      1. 提交:工程师将代码在本地测试后,提交到版本控制系统,如 Git代码仓库中。

      2. 构建:持续整合系统(如Jenkins CI),在检测到版本控制系统更新时,便自动从Git代码仓库里拉取最新的代码,进行编译、构建。

      3. 单元测试:Jenkins完成编译构建后,会自动执行指定的单元测试代码。

      4. 部署到测试环境:在完成单元测试后,Jenkins可以将应用程序部署到与生产环境相近的测试环境中进行测试。

      5. 预生产环境测试:在预生产测试环境里,可以进行一些最后的自动化测试,例如使用Appium自动化测试工具进行测试,以及与实际情况类似的一些测试可由开发人员或客户人员手动进行测试。

      6. 部署到生产环境:通过所有测试后,便可以使用灰度更新将最新的版本部署到实际生产环境里。

    而实现DevOps自动化流水线所需要哪些技术,它们又是如何配合使用的?带着这些问题,我将在DevOps的技术栈一节中详细为大家介绍。接下来让我们看看DevOps在游戏项目中实施所遇到的问题吧。

    DevOps在游戏项目遇到的问题

    问题一:游戏服务很难实现无状态化

    游戏服务架构与互联网架构差别还是很大的,由于游戏对实时性要求较高,所以很多游戏服很难使用分布式集中缓存,从而很难现实游戏服的无状态化,所以在互联网中成熟的微服务解决方案就不能直接应用到游戏中了,我会在后面具体介绍游戏与互联网的对比,以及游戏服如何拆分和解耦的。

    问题二:人手紧缺

    人员紧缺其实是很多公司的普遍问题,然而我经历过的游戏公司中,一个手游项目人员配备通常为:前端5-6人、后端3-4人、测试1-2人和1个运维。所以就很难有专门的人员去负责DevOps的自动化流程实现等了,只能抽空加班由自己推动落实。

    问题三:跨多部门协作,前期沟通培训成本高

    在转型的过程中,由于之前各部门间沟通协作隔着道“墙”,人员知识体系和认知不同,所以团队成员不支持或配合缓慢等。我们可以通过鼓励合作责任共担、建立自动化流程、推倒部门墙、营造DevOps文化奖励积极主动转变的行为、改变风险管理方式建立对失败的宽容环境。

    问题四:前期投入工作量大而见效少

    项目初期人员不足工期又紧的时候,还要做基础设施建设、人员沟通培训等,投入成本高而见效少,很容易让领导层失去信心。所以DevOps的实施也需要分阶段进行,逐步完善流程,以每阶段满足当前业务需求为基本准则,这也正是益精软件的原则。我在工作中一般分为三个时期:产品原型期、产品测试期和产品运营期。(请结合前面自动化流程一节中的“DevOps Pipeline”流水线图看下面三个时期的工作)

    • 产品原型期:此时处于开发的前期,所以我们一般只需要实现Git代码仓库、Jenkins CI集成和使用FindBugs或SonarQube执行静态代码分析等。

    • 产品测试期:在前面的基础上继续实现Jenkins集成Gradle实现自动构建打包、单元测试、部署到测试环境等流程。

    • 产品运营期:最后完善流水线,实现自动部署预生产环境和生产环境,实现灰度更新等。

    DevOps的思想先进、理念完美,是目前为止我觉得最好的解决方案,不过DevOps最终能够落地,很大程度上还是归功于它有一整套的技术和开源工具。接下来让我们一起看看DevOps想着的技术栈吧。

    技术栈

    本节内容如果展开的话涉及太多,我将概略地为大家介绍下目前常见的一些开源DevOps技术工具,大家可以根据自己的需求选择使用,当然也可以使用像VSTS(Visual Studio Team Services)这样的集成团队环境。

    其中有些内容在我的新书中有详细介绍,如代码仓库管理、虚拟机与容器化、持续集成&持续部署工具Jenkins、配置管理工具SaltStack。

    敏捷管理工具

    • Trello

    • Teambition

    • Worktile

    • Tower

    以上工具使用大同小异,选择一款适合自己团队的就好。我们公司主要使用的是Teambition,截张效果图如下:

    Teambition看板

    产品&质量管理

    • confluence

    • 禅道

    • Jira

    • Bugzila

    其中confluence和禅道主要是产品的需求、定义、依赖和推广等的全面管理工具;而Jira和Bugzilla是产品的质量管理和监控能力,包括测试用例、缺陷跟踪和质量监控等。目前我们使用Jira较多。

    代码仓库管理

    • Git

    • Gitlab

    • Github

    Git是一个开源的分布式版本控制系统;Gitlab和Github是用于仓库管理系统的开源项目,它们使用Git作为代码管理工具,并在此基础上搭建起来的web服务。我们主要使用的是Git和Gitlab。

    开发流程规范

    • Git Flow

      Git Flow是构建在Git之上的一个组织软件开发活动的模型,是在Git之上构建的一项软件开发最佳实践。Git Flow是一套使用Git进行源代码管理时的一套行为规范和简化部分Git操作的工具。Git Flow模型如下图:

      Git Flow模型

    • Github Flow

      Github Flow是Git Flow的一个更简单的替换方案,它只有一个feature分支和一个master分支,简单而干净。Github Flow模型如下图:

      Github Flow模型

    • Gitlab Flow

      GitHub Flow认为你可以通过合并feature分支直接把代码部署到线上。Gitlab Flow模型如下图:

      Gitlab Flow模型

    自动化构建脚本

    • Gradle

    • Maven

    • SBT

    • ANT

    我目前主要使用Gradle和Maven,而Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。面向Java应用为主。当前其支持的语言限于Java、Groovy、Kotlin和Scala。

    虚拟机与容器化

    • VMware

    • VirtualBox

    • Vagrant

    • Docker

    VMware和VirtualBox是最常用的虚拟机,支持非常多的平台,而Vagrant是构建在虚拟化技术之上的虚拟机运行环境管理工具。通过Vagrant可以方便实现的对虚拟机的管理,包括建立和删除虚拟机、配置虚拟机运行参数、管理虚拟机运行状态、自动化配置和安装开发环境必须的各类软件、打包和分发虚拟机运行环境等。

    Docker是一个开源的应用容器引擎,它让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。

    持续集成(CI)&持续部署(CD)

    • Jenkins

    • Hudson

    • Travis CI

    • CircleCI

    Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能,它的前身为Hudson。

    Travis CI 是目前新兴的开源持续集成构建项目,它与jenkins很明显的区别在于采用yaml格式,简洁清新独树一帜。

    CircleCI是一个为web应用开发者提供服务的持续集成平台,主要为开发团队提供测试,持续集成,以及代码部署等服务。

    自动化测试

    • Appium

      Appium是一个移动端的自动化框架,可用于测试原生应用,移动网页应用和混合型应用,且是跨平台的。可用于IOS和Android以及firefox的操作系统。

    • Selenium

      Selenium 测试直接在浏览器中运行,就像真实用户所做的一样。Selenium 测试可以在 Windows、Linux 和 Macintosh上的 Internet Explorer、Mozilla 和 Firefox 中运行。

    • Mock测试

      Mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。这个虚拟的对象就是Mock对象,Mock对象就是真实对象在调试期间的代替品。Java中的Mock框架常用的有EasyMock和Mockito等。

    • 消费者驱动契约测试

      契约测试是一种针对外部服务的接口进行的测试,它能够验证服务是否满足消费方期待的契约。当一些消费方通过接口使用某个组件的提供的行为时,它们之间就产生了契约。这个契约包含了对输入和输出的数据结构的期望,性能以及并发性。而PACT是目前比较流的消费者驱动契约测试框架。

    自动化运维工具

    • Ansible

    • Puppet

    • Chef

    IT运维自动化是指将IT运维中日常的、大量的重复性工作自动化,把过去的手工执行转为自动化操作。自动化是IT运维工作的升华,IT运维自动化不单纯是一个维护过程,更是一个管理的提升过程,是IT运维的最高层次,也是未来的发展趋势。下图为常用自动化运维工具对比:

    自动化运维管理工具对比图

    监控管理工具

    • Zabbix

      Zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级开源解决方案。

    • ELK Stack日志分析系统

      ELK Stack是开源日志处理平台解决方案,背后的商业公司是Elastic。它由日志采集解析工具 Logstash、基于 Lucene 的全文搜索引擎 Elasticsearch、分析可视化平台 Kibana三部分组成。

    • 云监控(如Amazon CloudWatch)

      Amazon CloudWatch 是一项针对 AWS 云资源和在 AWS 上运行的应用程序进行监控的服务。您可以使用 Amazon CloudWatch 收集和跟踪各项指标、收集和监控日志文件、设置警报以及自动应对 AWS 资源的更改

    游戏架构

    游戏行业与互联网行业的对比

    • 项目迭代周期对比

      互联网的迭代模式

      互联网的迭代模式

      游戏项目的开发周期

      游戏项目的开发周期

    通过上面的比对,我们可以看出互联网项目每次的需求迭代可以更敏捷、更快速,因为它可以把大的需求拆分为多个小的具体实现,这样能保证不断地持续交付和部署。

    而游戏相比互联网的迭代就会困难些、时间周期更长些,因为一款游戏能开始交付给用户,最基础的功能和玩法都要完备了才能测试和使用。

    • 请求通信机制对比

      游戏与互联网服务简单对比

    互联网中一般为请求-响应模式,通常情况下每次请求都是同步阻塞方式;而游戏中大多为请求-推送模式,不仅推送自己,还推送给游戏中其他的用户,游戏中每次请求都为异步非阻塞方式。

    小结:互联网服务器和游戏服务器最大的区别实际上就在于“状态”,游戏服务器的状态是实时快速变化的、可以容忍丢失的、需要大量广播同步的;而互联网服务器的状态一般是持久化的、不容忍丢失的、只和特定客户端相关的。所以在游戏中实现DevOps的难度比互联网大得多,而互联网成熟的实现方案也不能完全的照搬照抄到游戏中来。接下来我将从游戏构架—DevOps实施的源头—来分析介绍常见游戏服务架构是什么样的?

    常见游戏服务架构分析–DevOps根源

    • 休息卡牌游戏

      休息游戏架构

      这类游戏一般采用http通信模式,它的架构和常用的web服务器架构差不多,使用redis集中式缓存保存游戏状态,这样就能通过nginx进行负载,游戏服可以支持无限水平扩展。

    • 开房间游戏

      房间模式游戏架构

      这类型的游戏一般来说服务器端会分为两个部分:一是大厅服务器,一是房间服务器。大厅服务器是一个巨大的广播集群,负责不太实时的数据传输和查询。房间服务器是一组可以快速租用、退还的小型实时广播服务进程。

      在大厅服务器中,所有在线的玩家,都按其ID来分布在多个进程中的一个,在玩家之间的查询、广播操作时,采用多个服务器并行操作,最后汇总结果的方式来提供。这样的操作延迟是会比较高,但是能让海量的用户数据存储到不同的机器上;而房间服务器则只负责提供具体的游戏广播功能,一旦玩家组成了群组进入,大厅服务器会拷贝数据到房间服务器,而房间服务器就只对这几个玩家负责了,游戏结束则清理掉这些玩家数据,准备新的游戏。

    • 分服游戏

      RPG&SLG分服模式架构

      分服模型是游戏服务器中最典型,也是历久最悠久的。其特征是游戏服务器是一个个单独的世界,每个服务器的帐号是独立的,每台服务器用户的状态都是不一样的,一个服就是一个平行的世界,各服之间互不相干。

    • 全服模式

      RPG&SLG全服模式架构

      尽管分服的游戏模型已经运营了很多年,但是有一些游戏运营商还是希望能让尽量多的玩家一起玩,因为网游的人气越活跃,产生的交互越多,游戏的乐趣也就越多,所以就要求能开发出满足大量用户在线互动的游戏服务器模型——全服全线模型。

      SOA架构模式是一个经典的分布式软件架构模式,服务之间使用RPC运程调用功能,而服务的注册和发现则使用ZooKeeper这样的目录服务器。这样游戏服务就拆分为三层结构:最前边的网关(gate)服务器、中间为各游戏服务器(gameServer),最后边的数据库(DB)服务器。这样把网络功能单独提取出来,让用户统一去连接一个网关服务器,再由网关服务器转发数据到后端游戏服务器。而游戏服务器之间数据交换也统一连接到网关服进行交换。所有与DB交互的都连接到DB服务器来代理处理。

    小结:现在游戏服务器变得越来越大,不同游戏其实又具有很多相同的功能,所以如何把游戏服务进行拆分解耦,从而实现游戏的服务化就变得相当重要了,接下来我将进一步介绍游戏服务是如何拆分的?

    游戏服务的解耦–分而治之思想

    • 业务层面拆分

      业务层面拆分

      从业务层面,其实所有的RPG游戏都具有武将、属性、背包、任务和技术等五大基础系统,而各游戏的差异化大多在不同的玩法系统,业务系统和活动系统也有很多相似的地方。

    • 功能层面拆分

      功能层面拆分

      从功能层面,像登陆系统、客服系统、统计系统和监控系统我们也都可以做为通用的游戏服务,提供给各游戏项目使用,从而实现游戏业的SAAS平台。

    • 多维度架构

      多维度架构

      一套游戏平台面向不同的部门和人员,所以也需要从不同的维度考虑和构建,从而尽量满足大部分人的需求和便利。

    小结

    本章内容较多,首先从DevOps的理论开始介绍了,什么是DevOps,以及我们什么需要它,然后再结合实际一步步地介绍了DevOps的落地实践。而DevOps最终能被实现主要归功于它拥有丰富的开源技术工作,所以我们又介绍了目前常用的DevOps技术栈,最后通过对游戏行业的分析介绍,实现了游戏服务的拆分,最终从游戏系统构架层入手实现了DevOps在游戏中的落地。谢谢大家的支持!!

    【GitChat达人课】

    1. 前端恶棍 · 大漠穷秋 :《Angular 初学者快速上手教程
    2. Python 中文社区联合创始人 · Zoom.Quiet :《GitQ: GitHub 入味儿
    3. 前端颜值担当 · 余博伦:《如何从零学习 React 技术栈
    4. GA 最早期使用者 · GordonChoi:《GA 电商数据分析实践课
    5. 技术总监及合伙人 · 杨彪:《Gradle 从入门到实战
    6. 混元霹雳手 · 江湖前端:《Vue 组件通信全揭秘
    7. 知名互联网公司安卓工程师 · 张拭心:《安卓工程师跳槽面试全指南

    这里写图片描述

    展开全文
  • Mac+iOS平台实践番茄工作法之软件介绍 最近买了《番茄工作法图解》这本书,花了一个下午的时间仔细读完,然后觉得这是一个非常适合我的时间管理方法,因为我一直觉得高效工作就应该是集中一小段时间,然后...
  • Raft算法Curve实践

    万次阅读 2020-11-23 20:27:55
    下面首先简要介绍一下Raft算法的一些基本概念和术语,再详细介绍其Curve实践。 Raft一致性算法介绍 Raft算法,有Leader,Follower,Candidate三种角色,它们之间的转换关系如下图: 同一时刻,只能...
  • Linux内核实践工作队列

    千次阅读 2012-03-30 11:25:53
    工作队列可以把工作推后,交由一个内核线程去执行,也就是说,这个下半部分可以进程上下文执行。这样,通过工作队列执行的代码能占尽进程上下文的所有优势。最重要的就是工作队列允许被重新调度甚至是睡眠。 ...
  • 在工作中学习

    千次阅读 2012-12-29 16:55:22
    但是缺少编程实践,没有做过什么项目,自己也没有写过什么小软件(类似图书管理系统的),我自己写过实现一些功能的小程序(比如用mfc实现的计算器),学了1年多了,就知道看书、看视频,没有很好的编程实践。...
  • 最近项目需要用到工作流,所以又临时对Activiti工作流进行突击补习,再参考网上各大牛的技术博客,总算对Activiti有了一丢丢的了解及应用技巧。 开始做之前,我们要先学会制作工作流程图,网上都有介绍制图工具,...
  • 简析敏捷分布式团队实践

    千次阅读 2007-09-27 12:34:00
    什么是敏捷?简而言之,敏捷是一种新的软件开发的思想,...这儿可以用Kent Beck、Martin Fowler等16位业内权威的软件人士几年前所做的一个敏捷宣言来解释: 个体和交互胜过过程和工具 可工作软件胜过面面俱到的文档
  • Transformer 美团搜索排序实践

    千次阅读 2020-04-16 23:03:13
    模型结构 我们的模型结构参考 AutoInt[3] 结构,但在实践中,根据美团搜索的数据特点,我们对模型结构做了一些调整,如下图 2 所示: 相比 AutoInt[3],该结构有以下不同: 保留将稠密特征和离散特征的 Embedding ...
  • 组合功能Excel经常使用,可以很方便地将一组数据展开或者折叠 当我们需要将其所在工作表进行保护时,发现之前设定的组合无法使用了   此时,就需要我们VBA设定相关语句: PS:该方法转自Excelhome论坛 ...
  • 华为KubeEdge边缘计算的实践

    万次阅读 多人点赞 2018-12-05 16:09:34
    华为KubeEdge边缘计算的实践摘要1 介绍2 相关工作3 架构和设计3.1 KubeBus3.1.1 Edge Node VPN3.1.2 将边缘节点VPN与容器网络连接3.1.3 多租户管理/数据平面和服务发布 本篇文章是对华为论文的翻译,意让更多人...
  • 基于“定单”的工作实践

    千次阅读 2004-08-17 00:53:00
    说明:提出“雕塑”系统的理念后,朋友们不只给予了建议,更给我了实践的机会,这就是“雕塑”系统公司管理方面的实践日记,供大家参考和指正。 基于“定单”的公司版工作流管理: > 定单是每个工作岗位的交流...
  • Flink唯品会的实践

    千次阅读 2018-08-23 09:30:45
    本文来自于王新春2018年7月29日 Flink China社区线下 Meetup·上海站的分享。王新春目前唯品会负责实时平台相关内容,主要包括实时计算框架和提供实时基础数据,以及机器学习... Flink唯品会的实践 Flin...
  • ThoughtWorks的敏捷实践

    万次阅读 2016-05-03 10:24:29
    因为跟客户一起工作,就可以较为高效地组织Face2Face的会议,实践证明,Face2Face是效率最高的一种形式。 针对独立交付项目的Online形式。因为地点、时差等原因,适当调整Catch up的频率,另外选择一个便捷可靠...
  • 声明:本文来自「七牛云主办的架构师实践日——亿级移动应用架构最佳实践」的演讲内容整理。PPT、速记和现场演讲视频等参见“七牛架构师实践日”官网。 嘉宾:卜赫,七牛云布道师。 责编:钱曙光,关注架构和...
  • wireshark是一款抓包软件,比较易用,平常可以利用它抓包,分析协议或者监控网络,是一个比较好的工具,因为最近研究这个,所以就写一下教程,方便大家学习。 这里先说Wireshark的启动界面和抓包界面 启动界面...
  • 简介:bilibili资深运维工程师李宁分享《DCDN游戏应用加速实践》从bilibili游戏应用的效果和成本入手,深入浅出地分享DCDN全站加速游戏加速场景的应用。日前,云栖大会新一代CDN的技术突破与应用实践专场...
  • Python办公自动化实践1:从多个excel表提取数据并汇总到一个工作表页,表格,抽取,sheet 发表时间:2020-04-26 问题:从当前目录或子目录查询符合条件的excel表格,并从这些excel表格抽取符合条件的行汇总到...
  • 总结与思考 外卖运营分析的业务实践中,由于业务的复杂及应用场景的不同,没有哪一种数据生产方案能够解决所有业务问题。数据库引擎技术的发展,为我们提供更多手段提升数据建设方案。实践证明,以Doris引擎为...
  • Druid 小米公司部分技术实践

    千次阅读 2017-03-13 10:32:23
    Druid作为一款开源的实时大数据分析软件,自诞生以来,凭借自己优秀的特质,不仅逐渐技术圈收获了越来越多的知名度与口碑,并且陆续成为了很多技术团队解决方案的关键一环,从而真正很多公司的技术栈赢得了...
  • 我们有许多的公司为BIM摇旗呐喊,也做一些实实在在的研究和探索,并在实践中使用BIM。 这次全球的建筑业的设计与信息潮流中国没有落伍。   美国,欧洲很少看到城市里有建筑工地。中国的城市则现在处处...
  • OSOA组织的SCA规范升级到V1.0版本后,SCA的开源实现之一:apache组织的Tuscany项目SCA也随之快速的升级,并增加了对更多新标准和新技术的支持。1、支持使用更多格式的插件 升级后SCA (Tuscany项目的子项目,若无...
  • 在实践中学习,在实践中成长!不要局限于理论学习,书本学习。而且现在最重要的再实践中学习,实战技能。现在最需要培养的就是实战技能。实践经验。必须明确这些。 现在最需要的技能就是实战技能,一定要努力工作,...
  • AutoSAR系列讲解(实践篇)7.2-AppLDev的配置(上) AppLDev的配置(上) 一、Application Component Types(SWC Type) 二、Service Component Types 三、Data Types 1、Application Data Types 2、...
  • 公司接触到Drools,感觉可以为自己手头的工作所用,便开始着手Drools6规则引擎的研究之,采用最新的6.3版本,网上最新的额资源比较少,还要看不少英文介绍,前后忙了大概小半年,觉得有必要总结一下。...
  • vSwitch的主要功能是为物理机上的VM提供二层网络接入,和云环境的其它物理交换机 并行工作在Layer 2层。传统host ovs工作在内核态,与guest virtio的数据传输需要多次内核态和用户态的数据切换, 带来性能瓶颈. ...
  • Git Flow 团队的最佳实践 -- SourceTree的使用,文章来源一路博客,地址:http://www.16boke.com/article/detail/145

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 659,589
精华内容 263,835
关键字:

在工作实践中