Fork me on GitHub
行锋

低头走路,抬头思考


  • 首页

  • 分类

  • 归档

  • 标签

  • 关于

  • 搜索

redux-thunk

发表于 2018-10-26 | 分类于 React

简介

  • redux-thunk 是一个比较流行的 redux 异步 action 中间件,比如 action 中有 setTimeout 或者通过 fetch 通用远程 API 这些场景,那么久应该使用 redux-thunk 了
  • redux-thunk 帮助你统一了异步和同步 action 的调用方式,把异步过程放在 action 级别解决,对 component 没有影响
  • redux-thunk中间件可以让action创建函数先不返回一个action对象,而是返回一个函数,函数传递两个参数(dispatch,getState),在函数体内进行业务逻辑的封装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function add() {
return {
type: 'ADD',
}
}

function addIfOdd() {
return (dispatch, getState) => {
const currentValue = getState();
if (currentValue % 2 == 0) {
return false;
}
//分发一个任务
dispatch(add())
}
}

使用方式

  1. 安装:npm install redux-thunk --save-dev
  2. 导入thunk: import thunk from ‘redux-thunk’
  3. 导入中间件: import {createStore,applyMiddleware} from ‘redux’
  4. 创建store:let store = createStore(reducer函数,applyMiddleware(thunk))
  5. 激活redux-thunk中间件,只需要在createStore中加入applyMiddleware(thunk)就可以

React相关需学习

发表于 2018-10-26 | 分类于 React

ImmutableJS简介

ImmutableJS是FaceBook开发的一个JS库,能够在JS种实现不可变对象

不可变对象可以大大提高对象的比较性能,用于状态和属性判断非常有效

实际上,提高比较性能的代价是降低修改性能,只不过收益更大

Flux简介

Flux不是一个具体的框架,而是Facebook提出的一种代码架构

React只是一个视图库,Fulx是在React基础上对于前端整体的组织方案

Fulx目的是保证逻辑清晰、数据流向清晰、依赖关系清晰

Jest

发表于 2018-10-26 | 分类于 React

简介

Jest是一个JS的单元测试工具

单元测试可以保证函数或者模块完成我们想要的功能,测试具体功能是否正常

使用Jest需要配置NodeJS环境

入门

  1. npm install jest-cli
  2. sum.js
1
2
3
4
function sum(a,b){
return a+b;
}
module.exports=sum;
  1. test.js
1
2
3
4
5
6
7
8
jest.dontMock('../sum');

describe('sum',function(){
it('adds 1 + 2 to equal 3',function(){
var sum = require('../sum');
expect(sum(1,2)).toBe(3);
});
});

react-router-redux

发表于 2018-10-26 | 分类于 React

概述

用Redux去管理你的应用状态(state),使用React Router去管理路由,但是,这两个库不能协同工作,react-router-redux库可以协调这两个库

react-router-redux允许你使用React Router库中的api,使用Redux库像平常一样去管理应用的状态state。 本库只是简单的加强了React Router库中history这个实例,以允许将history中接受到的变化反应到stae中去。

原理示例

image
现在,你进行的所有页面导航和App导航,加强版的history会首先将新的路径通过Redux store传递,然后再通过React Router去更新组件树

Redux入门

发表于 2018-10-26 | 分类于 React
1
2
3
http://redux.js.org/
http://www.redux.org.cn/
http://www.imooc.com/learn/744 视频教程

简介

Redux 由 Flux 演变而来,但受 Elm 的启发,避开了 Flux 的复杂性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import { createStore } from 'redux';

/**
* 这是一个 reducer,形式为 (state, action) => state 的纯函数。
* 描述了 action 如何把 state 转变成下一个 state。
*
* state 的形式取决于你,可以是基本类型、数组、对象、
* 甚至是 Immutable.js 生成的数据结构。惟一的要点是
* 当 state 变化时需要返回全新的对象,而不是修改传入的参数。
*
* 下面例子使用 `switch` 语句和字符串来做判断,但你可以写帮助类(helper)
* 根据不同的约定(如方法映射)来判断,只要适用你的项目即可。
*/
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}

// 创建 Redux store 来存放应用的状态。
// API 是 { subscribe, dispatch, getState }。
let store = createStore(counter);

// 可以手动订阅更新,也可以事件绑定到视图层。
store.subscribe(() =>
console.log(store.getState())
);

// 改变内部 state 惟一方法是 dispatch 一个 action。
// action 可以被序列化,用日记记录和储存下来,后期还可以以回放的方式执行
store.dispatch({ type: 'INCREMENT' });
// 1
store.dispatch({ type: 'INCREMENT' });
// 2
store.dispatch({ type: 'DECREMENT' });
// 1

Redux 没有 Dispatcher 且不支持多个 store。相反,只有一个单一的 store 和一个根级的 reduce 函数(reducer)

image

中间件

1
2
3
4
5
6
7
8
9
10
11
12
13
redux-thunk — 用最简单的方式搭建异步 action 构造器
redux-promise — 遵从 FSA 标准的 promise 中间件
redux-axios-middleware — 使用 axios HTTP 客户端获取数据的 Redux 中间件
redux-observable — Redux 的 RxJS 中间件
redux-rx — 给 Redux 用的 RxJS 工具,包括观察变量的中间件
redux-logger — 记录所有 Redux action 和下一次 state 的日志
redux-immutable-state-invariant — 开发中的状态变更提醒
redux-unhandled-action — 开发过程中,若 Action 未使 State 发生变化则发出警告
redux-analytics — Redux middleware 分析
redux-gen — Redux middleware 生成器
redux-saga — Redux 应用的另一种副作用 model
redux-action-tree — Redux 的可组合性 Cerebral-style 信号
apollo-client — 针对 GraphQL 服务器及基于 Redux 的 UI 框架的缓存客户端

三大原则

Redux 可以用这三个基本原则来描述:

单一数据源

整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中

State 是只读的

惟一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象

使用纯函数来执行修改

为了描述 action 如何改变 state tree ,你需要编写 reducers;Reducer 只是一些纯函数,它接收先前的 state 和 action,并返回新的 state

总结

  1. 应用中所有的 state 都以一个对象树的形式储存在一个单一的 store 中
  2. 惟一改变 state 的办法是触发 action,一个描述发生什么的对象
  3. 为了描述 action 如何改变 state 树,你需要编写 reducers
  4. 编写专门的函数来决定每个 action 如何改变应用的 state,这个函数被叫做 reducer

安装

  1. 安装redux:npm install redux --save
  2. 使用 React 绑定库和开发者工具:npm install react-redux --save;npm install redux-devtools --save-dev

原理

image

Action

Action 是把数据从应用传到 store 的有效载荷,它是 store 数据的唯一来源。一般来说会通过 store.dispatch() 将 action 传到 store。

action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作.多数情况下,type 会被定义成字符串常量,建议使用单独的模块或文件来存放 action。除了 type 字段外,action 对象的结构完全由自己决定

1
import { ADD_TODO, REMOVE_TODO } from '../actionTypes'

Action 创建函数

Action 创建函数 就是生成 action 的方法

1
2
3
4
5
6
function addTodo(text) {
return {
type: ADD_TODO,
text
}
}

bindActionCreators() 可以自动把多个 action 创建函数 绑定到 dispatch() 方法上。

Reducer

永远不要在 reducer 里做这些操作:

  1. 修改传入参数;
  2. 执行有副作用的操作,如 API 请求和路由跳转;
  3. 调用非纯函数,如 Date.now() 或 Math.random()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter
})
case ADD_TODO:
return Object.assign({}, state, {
todos: [
...state.todos,
{
text: action.text,
completed: false
}
]
})
default:
return state
}
}
  1. 不要修改 state。 使用 Object.assign() 新建了一个副本。不能这样使用 Object.assign(state, { visibilityFilter: action.filter }),因为它会改变第一个参数的值。你必须把第一个参数设置为空对象。你也可以开启对ES7提案对象展开运算符的支持, 从而使用 { …state, …newState } 达到相同的目的。
  2. 在 default 情况下返回旧的 state
  3. Object.assign() 是 ES6 特性,但多数浏览器并不支持。你要么使用 polyfill,Babel 插件,或者使用其它库如 _.assign() 提供的帮助方法。
  4. 新的 todos 对象就相当于旧的 todos 在末尾加上新建的 todo。而这个新的 todo 又是基于 action 中的数据创建的

Store

Store 有以下职责:

  1. 维持应用的 state;
  2. 提供 getState() 方法获取 state;
  3. 提供 dispatch(action) 方法更新 state;
  4. 通过 subscribe(listener) 注册监听器;
  5. 通过 subscribe(listener) 返回的函数注销监听器

搭配react

Redux 和 React 之间没有关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。

连接到 Redux:我们需要做出两个变化,将 App 组件连接到 Redux 并且让它能够 dispatch actions 以及从 Redux store 读取到 state

  1. 获取从之前安装好的 react-redux 提供的 Provider,并且在渲染之前将根组件包装进
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//index.js
import React from 'react'
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './containers/App'
import todoApp from './reducers'

let store = createStore(todoApp);

let rootElement = document.getElementById('root')
render(
<Provider store={store}>
<App />
</Provider>,
rootElement
)
  1. 通过 react-redux 提供的 connect() 方法将包装好的组件连接到Redux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { addTodo, completeTodo, setVisibilityFilter, VisibilityFilters } from '../actions';
import AddTodo from '../components/AddTodo';
import TodoList from '../components/TodoList';
import Footer from '../components/Footer';

class App extends Component {
render() {
// 通过调用 connect() 注入:
const { dispatch, visibleTodos, visibilityFilter } = this.props
return (
<div>
<AddTodo
onAddClick={text =>
dispatch(addTodo(text))
} />
<TodoList
todos={this.props.visibleTodos}
onTodoClick={index =>
dispatch(completeTodo(index))
} />
<Footer
filter={visibilityFilter}
onFilterChange={nextFilter =>
dispatch(setVisibilityFilter(nextFilter))
} />
</div>
)
}
}

App.propTypes = {
visibleTodos: PropTypes.arrayOf(PropTypes.shape({
text: PropTypes.string.isRequired,
completed: PropTypes.bool.isRequired
})),
visibilityFilter: PropTypes.oneOf([
'SHOW_ALL',
'SHOW_COMPLETED',
'SHOW_ACTIVE'
]).isRequired
}

function selectTodos(todos, filter) {
switch (filter) {
case VisibilityFilters.SHOW_ALL:
return todos;
case VisibilityFilters.SHOW_COMPLETED:
return todos.filter(todo => todo.completed);
case VisibilityFilters.SHOW_ACTIVE:
return todos.filter(todo => !todo.completed);
}
}

// 基于全局 state ,哪些是我们想注入的 props ?
// 注意:使用 https://github.com/reactjs/reselect 效果更佳。
function select(state) {
return {
visibleTodos: selectTodos(state.todos, state.visibilityFilter),
visibilityFilter: state.visibilityFilter
};
}

// 包装 component ,注入 dispatch 和 state 到其默认的 connect(select)(App) 中;
export default connect(select)(App);

React Router

发表于 2018-10-26 | 分类于 React

https://reacttraining.com/react-router/

概述

React Router 4.0 (以下简称 RR4)

RR4 本次采用单代码仓库模型架构(monorepo),这意味者这个仓库里面有若干相互独立的包,分别是:

1
2
3
4
5
react-router React Router 核心
react-router-dom 用于 DOM 绑定的 React Router
react-router-native 用于 React Native 的 React Router
react-router-redux React Router 和 Redux 的集成
react-router-config 静态路由配置的小助手

它是官方维护的,事实上也是唯一可选的路由库。

react-router 还是 react-router-dom

  1. 在 React 的使用中,我们一般要引入两个包,react 和 react-dom
  2. react-router 和 react-router-dom 两个只要引用一个就行了,不同之处就是后者比前者多出了 这样的 DOM 类组件

学习

  • (阮一峰)http://www.ruanyifeng.com/blog/2016/05/react_router.html
  • (gitbook)http://react-guide.github.io/react-router-cn/docs/API.html

React入门

发表于 2018-10-26 | 分类于 React

简介

  • React 是一个用于构建用户界面的 JAVASCRIPT 库
  • React主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)
  • React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源
  • React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它
  • React 拥有一个强大的组合模型,我们建议使用组合而不是继承以实现代码的重用
  • react有 函数式组件和类组件,现在的使用都以类组件为主,函数式组件不考虑
  • angualr霸道,用了之后原生定时器、jquery等都不能用,而react没有这个限制
  • react中对事件的大小写敏感,因为有一个编译过程
  • 相关有用网址
1
2
3
官网:https://facebook.github.io/react/
中文网站:http://www.css88.com/react/
中文论坛:http://react-china.org/

react特点

  1. 声明式设计 −React采用声明范式,可以轻松描述应用。
  2. 高效 −虚拟DOM,React通过对DOM的模拟,最大限度地减少与DOM的交互。React DOM 会将元素及其子元素与之前版本逐一对比, 并只对有必要更新的 DOM 进行更新, 以达到 DOM 所需的状态
  3. 灵活 −React可以与已知的库或框架很好地配合。
  4. JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
  5. 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
  6. 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单

react全家桶(技术栈)

如果一个技术你不知道,那说明你还用不上

  1. react:主体
  2. webpack、grunt、gulp自动化构建工具
  3. Flex:布局
  4. react-route:路由
  5. redux:view层
  6. Mocha:测试
  7. Istanbul:覆盖率

安装

网页使用

网页中用babel会页面加载会有编译过程,比较缓慢,babel也可以后台编译

1
2
3
4
5
6
7
8
9
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
<script type="text/babel">
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
</script>

引入了三个库: react.min.js 、react-dom.min.js 和 babel.min.js:

  1. react.min.js - React 的核心库
  2. react-dom.min.js - 提供与 DOM 相关的功能
  3. babel.min.js - Babel 可以将 ES6 代码转为 ES5 代码,这样我们就能在目前不支持 ES6 浏览器上执行 React 代码。Babel 内嵌了对 JSX 的支持。通过将 Babel 和 babel-sublime 包(package)一同使用可以让源码的语法渲染上升到一个全新的水平

使用 create-react-app 快速构建

  • create-react-app 是来自于 Facebook,通过该命令我们无需配置就能快速构建 React 开发环境。
  • create-react-app 自动创建的项目是基于 Webpack + ES6
  • create-react-app网址:https://github.com/facebookincubator/create-react-app
  • create-react-app说明:https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#updating-to-new-releases
1
2
3
4
$ cnpm install -g create-react-app
$ create-react-app my-app
$ cd my-app/
$ npm start

在浏览器中打开 http://localhost:3000/,查看结果

JSX

JSX是可选的,对于使用 React而言不需要

React 使用 JSX 来替代常规的 JavaScript,JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。

优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化,需babel编译后才能运行,bower babel install,官网:http://babeljs.io/
  • 它是类型安全的,在编译过程中就能发现错误
  • 使用 JSX 编写模板更加简单快速

使用过程中的注意事项:

  1. 组件必须返回一个单独的根元素。render的内容必须有且仅有一个父元
  2. 网页中使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script src="js/react.js" charset="utf-8"/></script>
<script src="js/react-dom.js" charset="utf-8"/></script>
<script src="js/browser.js" charset="utf-8"/></script>
<script type="text/babel">
window.onload=function(){
var oDiv = document.getElementById("div1");
ReactDom.render(
<span>111</span>,//内容
oDiv//到哪
);
};
</script>
<body>
<div id="div1></div>
</body>
  1. 添加自定义属性需要使用 data- 前缀,因为jsx对html标签有识别,如果符合则不显示,而在自定义属性前面加data-可以保证显示显示
  2. 自定义组件可以单独文件存储
  3. 可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中;在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代
  4. React 推荐使用内联样式。我们可以使用 camelCase 语法来设置内联样式. React 会在指定元素数字后自动添加 px
  5. JSX 允许在模板中插入数组,数组会自动展开所有成员
  6. 注释:在标签内部的注释需要花括号;在标签外的的注释不能使用花括号
  7. 可以使用双引号来指定字符串字面量作为属性值
  8. class 在JSX中变为className,tabindex 变为 tabIndex
  9. React DOM 使用驼峰(camelCase)属性命名约定, 而不是HTML属性名称
1
2
3
4
5
ReactDOM.render(
/*注释 */
<h1>孙朝阳 {/*注释*/}</h1>,
document.getElementById('example')
);
  1. 如果你有一个单一模块(module) ,但却 导出(exports) 多个 React 组件时十分有用
1
2
3
4
5
6
7
8
9
10
11
import React from 'react';

const MyComponents = {
DatePicker: function DatePicker(props) {
return <div>Imagine a {props.color} datepicker here.</div>;
}
}

function BlueDatePicker() {
return <MyComponents.DatePicker color="blue" />;
}
  1. JSX 中的 Children:在 JSX 表达式中可以包含开放标签和闭合标签,标签中的内容会被传递一个特殊的 props(属性) : props.children

组件

  • 组件名称总是以大写字母开始
  • 组件有构造函数,构造函数的第一行应该是调用super函数,其参数为…args参数,在constructor方法中进行一些初始
  • 绑定事件的方式:onChange={this.函数名称.bind(this)}
  • 有狗那年,定时器中的this就不合适,在使用前通过_this=this保存一份,然后在定时中用_this代替
  • react处理了this,原生中如果要用this,最好也处理一下
  • react中阻止事件冒泡:ev.nativeEvent.stopImmediatePropergation
  • 父级属性传递给子级直接通过属性,子级属性传递给父级需要通过在父级绑定回调函数如cb(),在子级中通过this.props.cb(传递的参数)的方式把参数传递到父级
  • react中设置样式style需要通过双大括号}}来设置
  • 键(Keys) 帮助 React 标识哪个项被修改、添加或者移除了。数组中的每一个元素都应该有一个唯一不变的键(Keys)来标识。keys 只在数组的上下文中存在意义; keys 必须在它们的同辈之间唯一。然而它们并不需要全局唯一
  • 自定义组件的方式如下:
1
2
3
4
5
class 组件名称 extends React.Component{
render(){
retrun <span>我的年龄是:{this.props.age}</span>
}
}
1
2
3
4
5
6
//定义
class Comp extends React.Component{
render(){
return <span>111</span>;
}
}
  • 组件使用:类似于标签的使用
1
2
3
4
ReactDom.render(
<Comp age="18"/>,//内容,类名
document.body//到哪
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
window.onload=function(){ 
ReactDom.render(
<Comp/>,//内容,类名
document.body//到哪
);
};
~~~

# 状态state
* React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。
* React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
* this.setState({属性:'值'});
* state(状态) 更新可能是异步的。React 为了优化性能,有可能会将多个 setState() 调用合并为一次更新。因为 this.props 和 this.state 可能是异步更新的,你不能依赖他们的值计算下一个state(状态)。

# 属性props
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据

* 如果你没给 prop(属性) 传值,那么他默认为 true
* 控制表单的value,如果用props设置了默认值,由于props是死的,不能修改,修改为defaultValue即可
* 控制checkbox的默认值,修改为defalultChecked
* 属性扩展:如果你已经有一个 object 类型的 props,并且希望在 JSX 中传入,你可以使用扩展操作符 ... 传入整个 props 对象。以上两种方法等效:

function App1() {
return ;
}

function App2() {
const props = {firstName: ‘Ben’, lastName: ‘Hector’};
return <Greeting {…props} />;
}


# 组件生命周期
组件的生命周期可分成三个状态:
1. Mounting:已插入真实 DOM
2. Updating:正在被重新渲染
3. Unmounting:已移出真实 DOM

生命周期的方法有:
* componentWillMount 在渲染前调用,在客户端也在服务端
* componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异部操作阻塞UI)
* componentWillReceiveProps 在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用
* shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用
* componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用
* componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用
* componentWillUnmount在组件从 DOM 中移除的时候立刻被调用。==当使用异步加载数据时,在组件卸载前使用 componentWillUnmount 来取消未完成的请求==

# React Refs
* React 支持一种非常特殊的属性 Ref ,可以用来绑定到 render() 输出的任何组件上。
这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例
* 可以通过使用 this 来获取当前 React 组件,或使用 ref 来获取组件的引用
* ref 标示组件内的node,可以原生操作节点,在this.refs['ref名字']=原生
* React 支持给任何组件添加特殊属性。ref 属性接受回调函数,并且当组件 装载(mounted) 或者 卸载(unmounted) 之后,回调函数会立即执行
* 不能在函数式组件上使用 ref 属性,因为它们没有实例

# 使用 Chrome Timeline 分析组件性能
在 开发模式 中,你可以在支持相关功能的浏览器中使用性能工具来可视化组件 装载(mount) ,更新(update) 和 卸载(unmount) 的各个过程。在 Chrome 中具体操作如下: 
1. 通过添加 ?react_perf 查询字段加载你的应用(例如:http://localhost:3000/?react_perf)
2. 打开 Chrome DevTools Timeline 并点击 Record
3. 执行你想要分析的操作,不要超过20秒,否则 Chrome 可能会挂起
4. 停止记录
5. 在 User Timing 标签下,React事件将会分组列出

注意:上述数字是相对的,组件会在生产环境中会更快


# route
react-router + react-router-redux: 前者是业界标准,后者可以同步 route 信息到 state,这样你可以在 view 根据 route 信息调整展现,以及通过 action 来修改 route 。

docker 和vagrant比较

发表于 2018-10-18 | 分类于 docker

https://blog.csdn.net/carolzhang8406/article/details/80153869

Vagrant就是你的开发环境的部署工具;而docker是你的运行环境部署工具。

https://blog.csdn.net/terry_water/article/details/51813020
Vagrant 适合用来管理虚拟机,而docker适合用来管理应用环境。

vagrant

发表于 2018-10-18 | 分类于 docker

简介

Vagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境。它使用Oracle的开源VirtualBox虚拟化系统,使用 Chef创建自动化虚拟环境。

  • https://www.vagrantup.com/

  • https://www.virtualbox.org/

  • https://app.vagrantup.com/boxes/search

  • 入门:https://www.vagrantup.com/intro/getting-started/index.html

  • 官方文档:https://www.vagrantup.com/docs/index.html

(1)开发环境快速部署 (2)开发环境更迭

#Vagrant的主要概念

  • Provider:指的是为Vagrant提供虚拟化支持的具体软件,比如vmware或virtual box。
  • Box:代表虚拟机镜像。Vagrant根据Porvider的不同提供了很多的基础镜像(通过url从s3上获取),用户可以根据自己的需求使用vagrant package制作属于自己的box。
  • Project:一个目录和目录中的Vagrantfile就组成了vagrant的一个项目,项目下可以有子项目,子项目中的Vagrantfile配置将继承和重写父项目的配置。项目的虚拟机实例并不会存储在这个目录(存储在~/.vagrant.d/box下),所以可以通过git等版本管理工具来管理项目。
  • Vagrantfile:Vagrant的配置文件,使用Ruby的语法描述。里面定义了项目所使用的box,网络,共享目录,provision脚本等。当vagrant up命令运行时,将读取当前目录的Vagrantfile。
  • Provisioning:指的是虚拟机实例启动后,所需要完成的基础配置工作,比如说安装LAMP服务等。Vagrant支持使用shell,puppet,chef来完成provisioning工作。
  • Plugin:Vagrant提供了插件机制,可以很好的扩展对宿主机OS, GuestOS,Provider,Provisioner的支持,比如vagrant的aws和openstack支持都是通过plugin来实现的。

初始化第一个系统

1
2
3
4
5
6
7
8
9
10
mkdir centos7
cd centos7
vagrant init centos/7
vagrant up
vagrant ssh
sudo yum update
exit
vagrant status
vagrant halt
vagrant destroy

centos7默认账号/密码:vagrant/vagrant root/vagrant

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Usage: vagrant [options] <command> [<args>]

-v, --version Print the version and exit.
-h, --help Print this help.

Common commands:
box manages boxes: installation, removal, etc.
cloud manages everything related to Vagrant Cloud
destroy stops and deletes all traces of the vagrant machine
global-status outputs status Vagrant environments for this user
halt stops the vagrant machine
help shows the help for a subcommand
init initializes a new Vagrant environment by creating a Vagrantfile
login
package packages a running vagrant environment into a box
plugin manages plugins: install, uninstall, update, etc.
port displays information about guest port mappings
powershell connects to machine via powershell remoting
provision provisions the vagrant machine
push deploys code in this environment to a configured destination
rdp connects to machine via RDP
reload restarts vagrant machine, loads new Vagrantfile configuration
resume resume a suspended vagrant machine
snapshot manages snapshots: saving, restoring, etc.
ssh connects to machine via SSH
ssh-config outputs OpenSSH valid configuration to connect to the machine
status outputs status of the vagrant machine
suspend suspends the machine
up starts and provisions the vagrant environment
upload upload to machine via communicator
validate validates the Vagrantfile
version prints current and latest Vagrant version
winrm executes commands on a machine via WinRM
winrm-config outputs WinRM configuration to connect to the machine
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
vagrant box add "boxIdentity" remoteUrlorLocalFile 添加box
vagrant init "boxIdentity" 初始化box
vagrant up 启动虚拟机
vagrant ssh 登录虚拟机
vagrant box list 显示当前已添加的box列表
vagrant box remove "boxIdentity" 删除box
vagrant destroy 停止当前正在运行的虚拟机并销毁所有创建的资源
vagrant halt 关闭虚拟机
vagrant package 打包当前运行的虚拟机的环境
vagrant plugin 用于安装卸载插件
vagrant reload 重启虚拟机,主要用于重新载入配置文件
vagrant suspend 挂起虚拟机
vagrant resume 恢复挂起状态
vagrant ssh-config 输出ssh连接信息
vagrant status 输出当前虚拟机的状态
~~~

# Vagrantfile配置文件详解
* Vagrantfile 主要包括三个方面的配置,虚拟机的配置、SSH配置、Vagrant 的一些基础配置
* Vagrant 是使用 Ruby 开发的,所以它的配置语法也是 Ruby 的
* 修改完配置后需要执行 vagrant reload 重启 VM 使其配置生效

## 配置基本说明

Vagrant.configure(“2”) do |config|
# …
end

1
2
3
configure("2")描述的是使用Vagrant 2.0.x配置方式。

## box设置

config.vm.box = “centos/7”

1
2
3
4
5
6
配置Vagrant要去启用哪个box作为系统,默认名称为base

## 网络设置
Vagrant有两种方式进行网络连接.
* host-only主机模式,意思是主机与虚拟机之间的网络互访。其他人访问不到你的虚拟机。
* bridge桥接模式,此模式下VM如同局域网中的一台独立的直接虚拟机,可以被其他机器访问。

config.vm.network: private_network, ip: “11.11.11.11”

1
2
3
这里设置为host-only模式,且虚拟机ip设置为"11.11.11.11" 

## hostname设置

config.vm.hostname = “go-app”

1
2
3
4
host用于识别虚拟主机。特别在有多台虚拟机时,务必进行设置

## 同步目录
默认下,vagrant 共享的是你的项目目录(就是有vagrantfile文件的),除了默认的/vagrant同步目录外,还可以设置额外的同步目录:

config.vm.synced_folder “d:/local/dir”, “/vm/dir/”

1
2
3
第一个参数是本地目录,第二个参数为虚拟机目录。

## 端口转发

config.vm.network: forwarded_port, guest: 80, host: 8080

1
2
3
4
设置将主机上的8080端口forward到虚拟机的80端口上

# 单机配置
* 新建bootstrap.sh 文件

#!/usr/bin/env bash
apt-get update
apt-get install -y apache2
if ! [ -L /var/www ]; then
rm -rf /var/www
ln -fs /vagrant /var/www
fi

1
2

* 在Vagrantfile 中添加配置

Vagrant.configure(“2”) do |config|
config.vm.box = “hashicorp/precise64”
config.vm.provision :shell, path: “bootstrap.sh”
config.vm.network :forwarded_port, guest: 80, host: 4567
end

1
2
3
4
5
* 启动:vagrant up
* 验证:在浏览器上:http://127.0.0.1:4567

# 配置多台虚拟机
Vagrant支持单机启动多台虚拟机,支持一个配置文件启动多台。

Vagrant.configure(“2”) do |config|
config.vm.define :web do |web|
web.vm.provider “virtualbox” do |v|
v.customize [“modifyvm”, :id, “–name”, “web”, “–memory”, “512”]
end
web.vm.box = “base”
web.vm.hostname = “web”
web.vm.network :private_network, ip : “11.11.11.1”
end

config.vm.define :db do |db|
    db.vm.provider "virtualbox" do |v|
        v.customize ["modifyvm", :id, "--name", "db", "--memory", "512"]
    end
    db.vm.box = "base"
    db.vm.hostname = "db"
    db.vm.network :private_network, ip : "11.11.11.2"
end

end

1
2
3
4
5
6
7
8
9
10
这里使用了:web和:db定义了两个VM,设置完后再使用vagrant up启动。可以通过vagrant ssh web和vagrant ss db分别登录指定虚拟机上。
验证两台虚拟机间的通信: (验证方法: 在web虚拟机上通过ssh登录到db虚拟机)

https://blog.csdn.net/xiang__liu/article/details/80878571
https://max.book118.com/html/2017/0817/128451852.shtm

# 打包分发
当你配置好开发环境后,退出并关闭虚拟机。在终端里对开发环境进行打包:vagrant package

打包完成后会在当前目录生成一个 package.box 的文件,将这个文件传给其他用户,其他用户只要添加这个 box 并用其初始化自己的开发目录就能得到一个一模一样的开发环境了。

$ vagrant box add hahaha ~/box/package.box # 添加 package.box 镜像并命名为 hahaha
$ cd ~/dev # 切换到项目目录
$ vagrant init hahaha # 用 hahaha 镜像初始化。

1
2

# 集成预安装

上面这条看下来,你会发现每次都修改了一点点内容,再打包分发给其他用户其实很麻烦。为此 Vagrant 还提供了更为便捷的预安装定制。打开 Vagrantfile 文件末尾处有下面被注释的代码:

config.vm.provision “shell”, inline: <<-SHELL
apt-get update
apt-get install -y apache2
SHELL
没错,这段代码就是让你在初次运行 vagrant up 后,虚拟机创建过程众自动运行的初始化命令。 取消注释,把要预先安装的 php/mysql/redis 和配置之类的通通都写进去。初始化时这些程序都会根据你写好的方法安装并配置。

如果你不是初次运行,同时又修改了这里的命令,想让系统再次运行这里面的命令,你可以使用 vagrant reload --provision 进行重载。所以在这种情况下,你只要将 Vagrantfile 共享给团队的其他成员就可以了,其他成员运行相同的命令即可,是不是比打包分发要方便许多。

你还可以把要运行的命令单独写在一个文件里存放在相同的目录下,比如 bootstrap.sh:

#!/usr/bin/env bash

apt-get update
apt-get install -y apache2
if ! [ -L /var/www ]; then
rm -rf /var/www
ln -fs /vagrant /var/www
fi
然后在 Vagrantfile 里这样添加:

Vagrant.configure(“2”) do |config|
config.vm.box = “hashicorp/precise64”
…

config.vm.provision “shell”, path: “bootstrap.sh” # 添加这行
end
效果和直接写在 Vagrantfile 是一样的。


# 用 vagrant 快速部署 docker 虚拟机集群
* https://blog.csdn.net/pmlpml/article/details/53925542
* https://blog.csdn.net/u011781521/article/details/80291765

docker入门

发表于 2018-10-18 | 分类于 docker

简介

  • 官网:https://www.docker.com/
  • 中文社区:http://www.docker.org.cn/
  • docker尝鲜:https://labs.play-with-docker.com/

docker虚拟机架构
image

docker管理常用指令
image

  • Docker版本分为两个:Docker Community Edition (CE)和 Docker Enterprise Edition (EE)。
  • Docker是基于CS架构,系统有两个程序:docker服务端和docker客户端,是一种Linux容器管理技术
  • docker服务端是一个服务进程,管理着所有的容器;docker客户端则扮演着docker服务端的远程控制器,可以用来控制docker的服务端进程。
  • 大部分情况下,docker服务端和客户端运行在一台机器上。
  • Docker为容器引入了镜像,使得容器可以从预先定义好的模版(images)创建出来,并且这个模版还是分层的
  • Docker容器通过镜像启动,是镜像的启动和执行阶段,采用写时复制(copy on write)

云计算中的Docker虚拟机
image

Docker全家桶

image

Docker容器的能力

  1. 文件系统隔离:每个容器都有自己的root文件系统
  2. 进程隔离:每个容器都运行在自己的进程环境中
  3. 网络隔离:容器间的虚拟网络接口和IP地址都是分开的
  4. 资源隔离和分组:使用cgroups将CPU和内存之类的资源独立分配给每个Docker容器
  • docker Client客户端————>向docker服务器进程发起请求,如:创建、停止、销毁容器等操作
  • docker Server服务器进程—–>处理所有docker的请求,管理所有容器
  • docker Registry镜像仓库——>镜像存放的中央仓库,可看作是存放二进制的软件配置管理(scm)

docker安装

https://docs.docker.com/install/linux/docker-ce/ubuntu/

CentOS系统

1
2
3
yum -y update
yum -y install docker
service docker start|stop|restart

Ubuntu系统

1
2
3
sudo apt install docker.io
sudo systemctl start docker
sudo systemctl enable docker

下载安装完成之后docker version查看

免sudo使用docker命令

参考自网络:https://www.jianshu.com/p/95e397570896

1
2
3
4
sudo groupadd docker
sudo gpasswd -a ${USER} docker
sudo service docker restart
newgrp - docker

docker加速器配置

  • docker国内镜像仓库设置,官网:https://www.daocloud.io/
  • 配置加速:https://www.daocloud.io/mirror
1
sudo curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io

检查文件cat /etc/docker/daemon.json ,确保格式正确,无多余逗号,有则删除,如:

1
{"registry-mirrors": ["http://f1361db2.m.daocloud.io"]}

docker虚拟机安装java

  • docker search java #查找java镜像,如选择使用name为java的镜像
  • docker pull java

导出导入镜像

1
2
3
4
docker save java > /home/java.tar.gz    //save后面跟的是镜像的名称
docker load < /home/java.tar.gz
docker images
docker rmi

exit推出交互界面后也停止了容器,重新进入:docker start -i java

docker提供了一个开发,打包,运行app的平台,把app和底层infratructure隔离开来

docker底层技术支持,依赖于Linux内核特性Namespaces和Cgroups
Namespaces:做隔离pid,net,ipc,mnt,uts
Control Groups:做资源限制
Union file Systems:Container和image的分层

namespace,容器隔离的基础,保证A容器看不到B容器. 6个名空间:User,Mnt,Network,UTS,IPC,Pid
cgroups,容器资源统计和隔离。主要用到的cgroups子系统:cpu,blkio,device,freezer,memory
unionfs,典型:aufs/overlayfs,分层镜像实现的基础

docker镜像与容器

image

  • docker image:是容器的基石,本身为层叠的只读文件系统,
    docker通过联合加载技术一次加载多个文件系统,从外部看,只能看到一个文件系统,包含所有文件系统的文件和目录。bootfs-rootfs(如:ubuntu)-apache。。。,rootfs称为基础镜像
    文件和meta data的集合(root filesystem)
    分层的,并且每一层都可以添加改变删除文件,成为一个新的image
    不同的image可以共享x相同的layer
    image本身是read-only的
    sudo docker image ls
    docker history [imageID]

image的获取

  1. 通过Dockerfile
  2. 从Registry获取,如:docker pull ubuntu:14.04,https://hub.docker.com/
  3. 命令行的格式为:docker search 镜像名字

Container

docker容器可以理解为在沙盒中运行的进程。这个沙盒包含了该进程运行所必须的资源,包括文件系统、系统类库、shell 环境等等。但这个沙盒默认是不会运行任何程序的。你需要在沙盒中运行一个进程来启动某一个容器。这个进程是该容器的唯一进程,所以当该进程结束的时候,容器也会完全的停止。

通过Image创建
在Image Layer之上建立一个container layer(可读写)
类比面向对象:类和实例
Image负责app的存储和分发,Container负责运行app
container id只要能够区分出来就行,不用全部输入
docker container ls //运行的
docker container ls -a //所有的,包括退出的和正在运行的

docker run命令有两个参数,一个是镜像名,一个是要在镜像中运行的命令。

docker run [name] //运行container
docker run -it [name] //交互式运行container

命令简写
docker container ls -a == docker ps -a
docker container rm [conatinerID] == docker rm [conatinerID]
docker image ls == docker images
docker image rm [imageID] == docker rmi [imageID]

docker container ls -aq //列出所有conatinerID

构建自己的docker镜像
docker commit [containerName] [dockerhubID/imageNewName]

容器的操作
//对容器执行命令
docker exec
docker exec -it [containerID] /bin/bash
docker inspect [imageName] //查看
docker logs [containerID]

通过Dockerfile创建

  1. 新建空文件夹
  2. 创建Dockerfile文件
1
2
FROM [BaseImageName]    //如果没有则值为scratch
RUN yum install -y vim
  1. docker build -t [dockerhubID/imageNewName] . //.表示当前目录中查找Dockerfile
  2. docker image ls查看

Dockerfile语法梳理及最佳实践

  1. FROM:尽量使用官方的iamge作为base image
  2. LABEL:Metadata不可少,让大家了解到image的信息,相当于image的注释
  3. RUN:为了美观,复杂的RUN请用反斜线换行,避免无用分层,合并多条命令成一行
  4. WORKDIR:设定当前工作目录,如果没有则会自动创建目录;用WORKDIR,不要用RUN cd,尽量使用绝对目录
  5. ADD和COPY:把本地文件(构建目录中的相对地址 )添加到image里面,同时ADD添加的文件如果是压缩文件的话,会自动解压缩,大部分情况COPY优于ADD,添加远程文件/目录请使用crul或wget;目标路径需指定docker中的绝对路径
  6. ENV:设置环境变量,尽量使用ENV增加可维护性

https://github.com/docker-library/

1
2
3
4
5
6
7
8
9
MAINTAINER:指定容器的相关维护信息,维护人、邮箱等
RUN:执行命令并创建新的Image Layer,是在容器构建时执行
CMD:设置容器启动后默认执行的命令和参数,是在容器运行时运行的.如果docker run指定了其他命令,CMD命令被忽略;如果定义了多个CMD,只会执行最后一个;也可以只提供参数,作为ENTRYPOINT的默认参数
ENTRYPOINT:设置容器启动时运行的命令,让容器以应用程序或者服务的形式执行;不会被忽略,一定会执行;最佳实践是写一个shell脚本作为entrypoint
EXPOSE:指定运行该镜像的容器使用的端口,但此端口并未自动打开,在使用的时候需要映射/设置端口
VOLUME:用来向基于镜像创建的容器,一个卷是可以存在于一个或多个容器的特定目录,这个目录可以绕过联合文件系统提供共享数据、数据持久化功能
WORKDIR:用于在容器内部设置工作目录,一般使用绝对路径,如果使用相对路径,路径会一致传递下去
USER:用来指定镜像被什么用户去运行,如果不设置,默认为root用户
ONBUILD:用来为镜像添加触发器,当一个镜像被其他镜像作为基础镜像执行时,此触发器会被执行

使用中间层镜像进行调试,查找错误

docker build命令只删除了中间层常见的容器,但是没有删除中间层创建的镜像

构建缓存:构建过程中会产生缓存,下次构建直接使用缓存镜像,如果不想使用构建缓存,则可通过:docker build --no-cache,或者通过dockerfile文件的ENV REFRESH_DATE修改日期,则本条语句后就不使用缓存了

docker history 镜像,用来查看镜像的构建过程

1
2
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh "]

shell格式和EXEC格式

1
2
3
RUN apt-get install -y vim
CMD echo "Hello Docker"
ENTRYPOINT echo "Hello Docker"
1
2
3
RUN ["apt-get","install","-y","vim"]
CMD ["/bin/echo", "Hello Docker"]
ENTRYPOINT ["/bin/echo", "Hello Docker"]

登录dockerhub

docker login: 用户名(非邮箱)/密码

  1. 本地push上去,其他人就可以pull
  2. 关联github,github管理Dockerfile,有修改后自动build。Create-Create Automated build
  3. 通过docker的registry本地自己搭建。https://hub.docker.com/_/registry/,后期学习

Dockerfile实战

Dockerfile是docker构建镜像的基础,也是docker区别于其他容器的重要特征,正是有了Dockerfile,docker的自动化和可移植性才成为可能。
不论是开发还是运维,学会编写Dockerfile几乎是必备的

Docker常见命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
容器相关操作
docker create # 创建一个容器但是不启动它
docker run # 创建并启动一个容器
docker stop # 停止容器运行,发送信号SIGTERM
docker start # 启动一个停止状态的容器
docker restart # 重启一个容器
docker rm # 删除一个容器
docker kill # 发送信号给容器,默认SIGKILL
docker attach # 连接(进入)到一个正在运行的容器
docker wait # 阻塞到一个容器,直到容器停止运行
获取容器相关信息
docker ps # 显示状态为运行(Up)的容器
docker ps -a # 显示所有容器,包括运行中(Up)的和退出的(Exited)
docker inspect # 深入容器内部获取容器所有信息
docker logs # 查看容器的日志(stdout/stderr)
docker events # 得到docker服务器的实时的事件
docker port # 显示容器的端口映射
docker top # 显示容器的进程信息
docker diff # 显示容器文件系统的前后变化
导出容器
docker cp # 从容器里向外拷贝文件或目录
docker export # 将容器整个文件系统导出为一个tar包,不带layers、tag等信息
执行
docker exec # 在容器里执行一个命令,可以执行bash进入交互式
镜像操作
docker images # 显示本地所有的镜像列表
docker import # 从一个tar包创建一个镜像,往往和export结合使用
docker build # 使用Dockerfile创建镜像(推荐)
docker commit # 从容器创建镜像
docker rmi # 删除一个镜像
docker load # 从一个tar包创建一个镜像,和save配合使用
docker save # 将一个镜像保存为一个tar包,带layers和tag信息
docker history # 显示生成一个镜像的历史命令
docker tag # 为镜像起一个别名
镜像仓库(registry)操作
docker login # 登录到一个registry
docker search # 从registry仓库搜索镜像
docker pull # 从仓库下载镜像到本地
docker push # 将一个镜像push到registry仓库中

docker system df //查看镜像、容器、数据卷所占用的空间
docker commit -m "ubuntu with vim" -a "sgy" aa97ba3292ce sgy/ubuntu:vim

https://www.ghostcloud.cn/

服务器虚拟化 (vsphere cas ZStack不通厂家命名):裸机虚拟化、半裸机虚拟化
网络虚拟化 SDN
存储虚拟化 VSAN 服务器做raid保证系统安全,然后做存储虚拟化

Mac 上的 Docker 背后应该是一个 Linux 虚机,和 Windows 版本的 Docker 是一样的原理

容器一旦被直接推出,之前安装的gcc啊vim啊啥的就会全部gg掉。如果要保存修改,就需要将当前容器封装成一个新的镜像,这样下次启动这个新的镜像后之前作出的修改还都在。

容器不适合构建那种发布周期以周或月为单位的大型单一架构企业软件,容器适合采用微服务的方式,以及探索诸如持续部署这样的技术,使得我们能安全地在一天内多次更新生产环境。

https://blog.csdn.net/xdy3008/article/details/74531125

https://www.missshi.cn/api/view/blog/5a6327c00a745f6335000004

想看到docker容器的ip地址,只需要安装net-tools就可以了:yum install net-tools -y

如果你仅仅是想管理虚拟机,那么你应该使用vagrant。如果你想快速开发和部署应用,那么应该使用docker。
vagrant是一款管理虚拟机的工具,而docker是一款通过将应用打包到轻量级容器,而实现构建和部署的工具。两者适用范围不同。一个容器就是一个包含了应用执行所依赖的数据(包括lib,配置文件等等)。它可以保证应用在一个可重复的环境中随时执行。

数据卷:是经过特殊设计的目录,可以绕过联合文件系统ufs,为一个或多个容其提供访问。让你可以不受容器生命周期影响进行数据持久化。它们表现为容器内的空间,但实际保存在容器之外,从而允许你在不影响数据的情况下销毁、重建、修改、丢弃容器。
Docker允许你定义应用部分和数据部分,并提供工具让你将他们分开。容器是短暂和一次性的。
docker run -v ~/container_data:/data:ro -it centos,映射本地~/container_data到容器/data下,且/data的权限为ro只读,登录进去后ls查看,发现会有data目录

数据卷容器:命名的容器挂载数据卷,其他容器通过挂载这个容器实现数据共享,挂载数据卷的容器,就叫做数据卷容器。
docker run --volumes-from 数据卷容器名称
即使删除了数据卷容器,挂载了数据卷容器的容器,仍然可以访问数据卷容器的目录,数据卷容器起的作用仅仅是将挂载配置传递到待挂载容器

Docker数据卷的备份与还原:通过挂载目录压缩后放到挂载目录

Docker For Mac的Docker Daemon是运行于虚拟机(xhyve)中的, 而不是像Linux上那样作为进程运行于宿主机,因此Docker For Mac没有docker0网桥,不能实现host网络模式,host模式会使Container复用Daemon的网络栈(在xhyve虚拟机中),而不是与Host主机网络栈,这样虽然其它容器仍然可通过xhyve网络栈进行交互,但却不是用的Host上的端口(在Host上无法访问)。bridge网络模式 -p 参数不受此影响,它能正常打开Host上的端口并映射到Container的对应Port。

docker容器的网络连接

image
docker0:是Linux的虚拟网桥(网桥是数据链路层的一种设备),Linux的虚拟网桥可以设置IP地址,相当于拥有一个隐藏的虚拟网卡
docker0地址划分:IP127.17.42.1,掩码255.255.0.0,总共提供了65534个地址
网桥操作需安装bridge-utils工具,安装之后brctl show查看网桥信息,可以添加网桥或者配置网桥信息
docker容器的IP地址在重启容器之后会变化,是不可靠的

容器互联:在同一宿主机下,docker容器是通过虚拟网桥互相连接的,默认在同一宿主机下docker允许所有容器互联。让容器之间可以相互连接主要借用了一个link的功能。 在使用纯Docker时,被连接的容器必须在同一个Docker宿主机中。不同宿主机之间的容器如果想要连接,则需要借助Swarm或Kubernetes等编排工具。
–link:链接容器,docker run -it --name cct3 --link=cct1:webtest bitchofgod/testnet (webtest为cct1的别名),然后在cct3中ping webtest即可互联
Docker在父容器中的以下两个地方写入了连接信息:
/etc/hosts文件中,–link在此文件中写入了映射信息,当docker重新启动的时候,docker会自动维护此文件中的映射
包含连接信息的环境变量中
如果拒绝所有容器互联,则修改docker配置,在/ect/default/docker文件中添加DOCKER_OPTS=" --icc=false"后重启docker服务即可
如果需要特定容器互联,则通过–link、–icc=false、–iptables=true来实现

docker容器与外部网络的连接
ipforward
iptables

Ctrl+p,Ctrl+q退出交互界面
docker attach containerName重新打开交互界面

CaaS(Container as a Service):镜像容器托管
从Docker到Caas
容器集群管理工具
容器调度
配置管理
服务发现
日志/监控/报警

LaaS(基础设施) 出租计算、存储、网络、DNS等基础IT服务
PaaS(基础设施+系统平台—应用服务器应用框架 编程语言) 提供应用运行和开发环境 提供应用开发组件(邮件、消息、计费、支付)
SaaS (基础设施+系统平台+软件应用)互联网Web2.0应用 企业应用(ERP/CRM等)

通俗点讲
SaaS:软件即服务,简单来说就是把企业想要的功能开发好成应用软件,然后直接卖给用户使用。通俗点讲就是去饭店吃饭一样,什么都是店家的。
PaaS:平台即服务,简单来说就是云计算平台提供硬件、编程语言、开发库等帮助用户更好更快的开发软件。通俗来说就是点外卖,使用时店家的,但是餐桌是自己的。
IaaS:基础设施即服务,简单来说就是云服务商提供企业所需要的服务器、存储、网络给企业用。通俗来说就是买菜买面,回家自己做饭。

https://blog.csdn.net/weixin_38003389/article/details/84025762

Docker Machine:目的是简化 Docker 的安装和远程管理,是官方提供的一个工具。
先创建Docker Machine机器

Docker Compose:Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责快速在集群中部署分布式应用。
Docker Compose允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)
Compose 中有两个重要的概念:
项目 ( project ):由一组关联的应用容器组成的一个完整业务单元,在 dockercompose.yml 文件中定义。
服务 ( service ):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例
运行 compose 项目:docker-compose up

Docker Compose命令集

Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署,显然 Docker Swarm 会更加适合

1
2
3
4
管理镜像:build/pull
管理服务:up/start/stop/kill/rm/scale
服务状态:ps/logs/port
一次性服务:run

https://www.jianshu.com/p/658911a8cff3

Docker Swarm:Docker集群管理工具,支持标准的Docker API,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。
Swarm和Kubernetes比较类似,但是更加轻,具有的功能也较kubernetes更少一些。

三大主流调度框架

Swarm、Kubernetes和Mesos

参考文章

  • http://www.cnblogs.com/SzeCheng/p/6822905.html
1…111213…50
行锋

行锋

496 日志
15 分类
74 标签
GitHub E-Mail
自古写字楼如青楼,不许楼里见白头
© 2015 — 2019 行锋
博客全站共229.9k字