更新了团队项目相关内容
|
@ -1,89 +0,0 @@
|
|||
## 英语面试
|
||||
|
||||
以下用I表示面试官(Interviewer),用C表示面试者(Candidate)。
|
||||
|
||||
### 开场寒暄
|
||||
|
||||
1. I: Thanks for waiting. (Please follow me.)
|
||||
|
||||
C: It's no problem.
|
||||
|
||||
2. I: How are you doing this morning?
|
||||
|
||||
C: I'm great. / I'm doing fine. Thank you. / How about you?
|
||||
|
||||
3. I: How did you get here?
|
||||
|
||||
C: I took the subway here. / I drove here.
|
||||
|
||||
4. I: Glad to meet you.
|
||||
|
||||
C: Glad to meet you. / It's great to finally meet you in person. (之前电话沟通过的)
|
||||
|
||||
### 正式面试
|
||||
|
||||
#### 人力面试
|
||||
|
||||
1. I: Can you tell me a little bit about yourself? (介绍下自己)
|
||||
|
||||
原则:不要谈私生活和奇怪的癖好(英雄联盟干到钻石),因为别人更想知道的是你的专业技能(qulifications)和工作经验(experience),所以重点在你之前的公司(company name)、职位(title)、时间(years)和主要职责(major responsibilities)
|
||||
|
||||
C: Thank you for having me. My name is Dachui WANG. I'm 25 years old, and I'm single. I have a Bachelor's Degree of Computer Science from Tsinghua University. I was a Junior Java Programmer for ABC Technologies during my college life. Then I become an intermediate Java engineer for XYZ Corporation in last two years. Programming is my everyday life and programming is where my passion is. I think I have a good knowledge of Java enterprise application developement using light-weight frameworks like Spring, Guice, Hibernate and other open source middle-ware like Dubbo, Mycat, rocketmq and so on and so forth. I love reading, travelling and playing basketball in my spare time. That's all! Thank you!
|
||||
|
||||
2. I: How would you describe your personality? (你的性格)
|
||||
|
||||
C: I'm hard working, eager to learn, and very serious about my work. I enjoy working with other people and I love challenges.
|
||||
|
||||
3. I: What do you know about our company? (你对我们公司有什么了解)
|
||||
|
||||
(需要做功课,了解公司的状况和企业文化,该公司在这个行业中的一个状况,有什么核心业务,主要的竞争对手有哪些)
|
||||
|
||||
C: The one thing that I like the most about our company is your core values. I think they're very important in this industry because …(自由发挥的部分)... I personally really believe in the cause as well. Of course, I'm very interested in your products such as …(功课部分)… and the techniques behind them.
|
||||
|
||||
4. I: Why are you leaving your last job? (为什么离职)
|
||||
|
||||
C: I want to advance my career and I think this job offers more challenges and opportunities for me do to that.
|
||||
|
||||
5. I: What do you see yourself in 3 or 5 years? (3-5年职业规划)
|
||||
|
||||
C: My long term goals involve growing with the company, where I can continue to learn, to take on additional responsibilities and to contribute as much value as I can. I intend to take advantage of all of these.
|
||||
|
||||
6. I: What's your salary expectation? (期望薪资)
|
||||
|
||||
C: My salary expectation is in line with my experience and qualifications. I believe our company will pay me and every other employee fairly. (把球踢给对方先看看对方报价是多少,如果对方非要你报价再说后面的内容) I think 15 thousands RMB or above is fitting for me to leave in Chengdu.
|
||||
|
||||
7. I: Do you have any questions for me? (问面试官的问题)
|
||||
|
||||
C: What's the growth potential for this position?
|
||||
|
||||
|
||||
#### 技术面试
|
||||
|
||||
1. I: What's difference between an interface and an abstract class?
|
||||
2. I: What are pass by reference and pass by value?
|
||||
3. I: What's the difference between process and threads?
|
||||
4. I: Explain the available thread state in high-level.
|
||||
5. I: What's deadlocks? How to avoid them?
|
||||
6. I: How HashMap works in Java?
|
||||
7. I: What's the difference between ArrayList and LinkedList? (类似的问题还有很多,比如比较HashSet和TreeSet、HashMap和Hashtable)
|
||||
8. I: Tell me what you know about garbage collection in Java.
|
||||
9. I: What're two types of exceptions in Java?
|
||||
10. I: What's the advantage of PreparedStatement over Statement?
|
||||
11. I: What's the use of CallableStatement?
|
||||
12. I: What does connection pool mean?
|
||||
13. I: Explain the life cycle of a Servlet.
|
||||
14. I: What's the difference between redirect and forward?
|
||||
15. I: What's EL? What're implicit objects of EL?
|
||||
16. I: Tell me what you know about Spring framework and its benefits.
|
||||
17. I: What're different types of dependency injection.
|
||||
18. I: Are singleton beans thread safe in Spring framework?
|
||||
19. I: What're the benefits of Spring framework's transaction management?
|
||||
20. I: Explain what's AOP.
|
||||
21. I: What's a proxy and how to implement proxy pattern?
|
||||
22. I: How Spring MVC works?
|
||||
23. I: What's the working scenario of Hibernate and MyBatis?
|
||||
24. I: How to implement SOA?
|
||||
25. I: Make a brief introduction of the projects you are involved before?
|
||||
|
||||
|
||||
上面主要是面试Java程序员的问题,但是整个流程大致如此。
|
|
@ -1,745 +0,0 @@
|
|||
## 项目部署上线指南
|
||||
|
||||
### 准备上线
|
||||
|
||||
1. 上线前的检查工作。
|
||||
|
||||
```Shell
|
||||
python manage.py check --deploy
|
||||
```
|
||||
|
||||
2. 将DEBUG设置为False并配置ALLOWED_HOSTS。
|
||||
|
||||
```Python
|
||||
DEBUG = False
|
||||
ALLOWED_HOSTS = ['*']
|
||||
```
|
||||
|
||||
3. 安全相关的配置。
|
||||
|
||||
```Python
|
||||
# 保持HTTPS连接的时间
|
||||
SECURE_HSTS_SECONDS = 3600
|
||||
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
|
||||
SECURE_HSTS_PRELOAD = True
|
||||
|
||||
# 自动重定向到安全连接
|
||||
SECURE_SSL_REDIRECT = True
|
||||
|
||||
# 避免浏览器自作聪明推断内容类型
|
||||
SECURE_CONTENT_TYPE_NOSNIFF = True
|
||||
|
||||
# 避免跨站脚本攻击
|
||||
SECURE_BROWSER_XSS_FILTER = True
|
||||
|
||||
# COOKIE只能通过HTTPS进行传输
|
||||
SESSION_COOKIE_SECURE = True
|
||||
CSRF_COOKIE_SECURE = True
|
||||
|
||||
# 防止点击劫持攻击手段 - 修改HTTP协议响应头
|
||||
# 当前网站是不允许使用<iframe>标签进行加载的
|
||||
X_FRAME_OPTIONS = 'DENY'
|
||||
```
|
||||
|
||||
4. 敏感信息放到环境变量或文件中。
|
||||
|
||||
```Python
|
||||
SECRET_KEY = os.environ['SECRET_KEY']
|
||||
|
||||
DB_USER = os.environ['DB_USER']
|
||||
DB_PASS = os.environ['DB_PASS']
|
||||
|
||||
REDIS_AUTH = os.environ['REDIS_AUTH']
|
||||
```
|
||||
|
||||
### 更新服务器Python环境到3.x
|
||||
|
||||
1. 安装底层依赖库。
|
||||
|
||||
```Shell
|
||||
yum -y install wget gcc zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel
|
||||
```
|
||||
|
||||
2. 下载Python源代码。
|
||||
|
||||
```Shell
|
||||
wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tar.xz
|
||||
```
|
||||
|
||||
3. 解压缩和解归档。
|
||||
|
||||
```Shell
|
||||
xz -d Python-3.7.0.tar.xz
|
||||
tar -xvf Python-3.7.0.tar
|
||||
```
|
||||
|
||||
4. 执行配置生成Makefile(构建文件)。
|
||||
|
||||
```Shell
|
||||
cd Python-3.7.0
|
||||
./configure --prefix=/usr/local/python37 --enable-optimizations
|
||||
```
|
||||
|
||||
5. 构建和安装。
|
||||
|
||||
```Shell
|
||||
make && make install
|
||||
```
|
||||
|
||||
6. 配置PATH环境变量并激活。
|
||||
|
||||
```Shell
|
||||
cd ~
|
||||
vim .bash_profile
|
||||
```
|
||||
|
||||
```INI
|
||||
... 此处省略上面的代码...
|
||||
|
||||
export PATH=$PATH:/usr/local/python37/bin
|
||||
|
||||
... 此处省略下面的代码...
|
||||
```
|
||||
|
||||
```Shell
|
||||
source .bash_profile
|
||||
```
|
||||
|
||||
7. 注册软链接(符号链接)。
|
||||
|
||||
```Shell
|
||||
ln -s /usr/local/python37/bin/python3.7 /usr/bin/python3
|
||||
ln -s /usr/local/python37/bin/pip3.7 /usr/bin/pip3
|
||||
```
|
||||
|
||||
8. 测试Python环境是否更新成功。
|
||||
|
||||
```Shell
|
||||
python3 --version
|
||||
python --version
|
||||
```
|
||||
|
||||
### 项目目录结构
|
||||
|
||||
假设项目文件夹为`project`,下面的四个子目录分别是:`conf`、`logs`、`src`和`venv`分别用来保存项目的配置文件、日志文件、源代码和虚拟环境。其中,`conf`目录下的子目录`cert`中保存了配置HTTPS需要使用的证书和密钥;`src`目录下的项目代码可以通过版本控制工具从代码仓库中检出;虚拟环境可以通过venv或其他工具进行创建。
|
||||
|
||||
```
|
||||
project
|
||||
├── conf
|
||||
│ ├── cert
|
||||
│ │ ├── 214915882850706.key
|
||||
│ │ └── 214915882850706.pem
|
||||
│ ├── nginx.conf
|
||||
│ └── uwsgi.ini
|
||||
├── logs
|
||||
│ ├── access.log
|
||||
│ ├── error.log
|
||||
│ └── uwsgi.log
|
||||
├── requirements.txt
|
||||
├── src
|
||||
│ └── fangall
|
||||
│ ├── api
|
||||
│ ├── common
|
||||
│ ├── fang
|
||||
│ ├── rent
|
||||
│ ├── user
|
||||
│ ├── manage.py
|
||||
│ ├── README.md
|
||||
│ ├── static
|
||||
│ └── templates
|
||||
│
|
||||
└── venv
|
||||
├── bin
|
||||
│ ├── activate
|
||||
│ ├── activate.csh
|
||||
│ ├── activate.fish
|
||||
│ ├── celery
|
||||
│ ├── celerybeat
|
||||
│ ├── celeryd
|
||||
│ ├── celeryd-multi
|
||||
│ ├── coverage
|
||||
│ ├── coverage3
|
||||
│ ├── coverage-3.7
|
||||
│ ├── django-admin
|
||||
│ ├── django-admin.py
|
||||
│ ├── easy_install
|
||||
│ ├── easy_install-3.7
|
||||
│ ├── pip
|
||||
│ ├── pip3
|
||||
│ ├── pip3.7
|
||||
│ ├── __pycache__
|
||||
│ ├── pyrsa-decrypt
|
||||
│ ├── pyrsa-decrypt-bigfile
|
||||
│ ├── pyrsa-encrypt
|
||||
│ ├── pyrsa-encrypt-bigfile
|
||||
│ ├── pyrsa-keygen
|
||||
│ ├── pyrsa-priv2pub
|
||||
│ ├── pyrsa-sign
|
||||
│ ├── pyrsa-verify
|
||||
│ ├── python -> python3
|
||||
│ ├── python3 -> /usr/bin/python3
|
||||
│ └── uwsgi
|
||||
├── include
|
||||
├── lib
|
||||
│ └── python3.7
|
||||
├── lib64 -> lib
|
||||
├── pip-selfcheck.json
|
||||
└── pyvenv.cfg
|
||||
```
|
||||
|
||||
下面以阿里云为例,简单说明如何为项目注册域名、解析域名以及购买权威机构颁发的证书。
|
||||
|
||||
1. [注册域名](https://wanwang.aliyun.com/domain/)。
|
||||
|
||||
![](./res/aliyun-domain.png)
|
||||
|
||||
2. [域名备案](https://beian.aliyun.com/)。
|
||||
|
||||
![](./res/aliyun-keeprecord.png)
|
||||
|
||||
3. [域名解析](https://dns.console.aliyun.com/#/dns/domainList)。
|
||||
|
||||
![](./res/aliyun-dnslist.png)
|
||||
|
||||
![](./res/aliyun-resolve-settings.png)
|
||||
|
||||
4. [购买证书](https://www.aliyun.com/product/cas)。
|
||||
|
||||
![](./res/aliyun-certificate.png)
|
||||
|
||||
### uWSGI的配置
|
||||
|
||||
1. 在`project`目录下创建并激活虚拟环境。
|
||||
|
||||
```Shell
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
```
|
||||
|
||||
2. 安装项目依赖项。
|
||||
|
||||
```Shell
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
3. 通过pip安装uWSGI。
|
||||
|
||||
```Shell
|
||||
pip install uwsgi
|
||||
```
|
||||
|
||||
4. 修改uWSGI的配置文件(`/root/project/conf/uwsgi.ini`)。
|
||||
|
||||
```INI
|
||||
[uwsgi]
|
||||
# 配置前导路径
|
||||
base=/root/project
|
||||
# 配置项目名称
|
||||
name=fangall
|
||||
# 守护进程
|
||||
master=true
|
||||
# 进程个数
|
||||
processes=4
|
||||
# 虚拟环境
|
||||
pythonhome=%(base)/venv
|
||||
# 项目地址
|
||||
chdir=%(base)/src/%(name)
|
||||
# 指定python解释器
|
||||
pythonpath=%(pythonhome)/bin/python
|
||||
# 指定uwsgi文件
|
||||
module=%(name).wsgi
|
||||
# 通信的地址和端口(自己服务器的IP地址和端口)
|
||||
socket=172.18.61.250:8000
|
||||
# 日志文件地址
|
||||
logto = %(base)/logs/uwsgi.log
|
||||
```
|
||||
|
||||
> 说明:可以先将“通信的地址和端口”项等号前面改为http来进行测试,如果没有问题再改回 成socket,然后通过Nginx来实现项目的“动静分离”(静态资源交给Nginx处理,动态内容交给 uWSGI处理)。按照下面的方式可以启动uWSGI服务器。
|
||||
|
||||
5. 启动服务器。
|
||||
|
||||
```Shell
|
||||
uwsgi --ini uwsgi.ini &
|
||||
```
|
||||
|
||||
### Nginx的配置
|
||||
|
||||
1. 修改全局配置文件(`/etc/nginx/nginx.conf`)。
|
||||
|
||||
```Nginx
|
||||
# 配置用户
|
||||
user root;
|
||||
# 工作进程数(建议跟CPU的核数量一致)
|
||||
worker_processes auto;
|
||||
# 错误日志
|
||||
error_log /var/log/nginx/error.log;
|
||||
# 进程文件
|
||||
pid /run/nginx.pid;
|
||||
# 包含其他的配置
|
||||
include /usr/share/nginx/modules/*.conf;
|
||||
# 工作模式和连接上限
|
||||
events {
|
||||
use epoll;
|
||||
worker_connections 1024;
|
||||
}
|
||||
# HTTP服务器相关配置
|
||||
http {
|
||||
# 日志格式
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
# 访问日志
|
||||
access_log /var/log/nginx/access.log main;
|
||||
# 开启高效文件传输模式
|
||||
sendfile on;
|
||||
# 用sendfile传输文件时有利于改善性能
|
||||
tcp_nopush on;
|
||||
# 禁用Nagle来解决交互性问题
|
||||
tcp_nodelay on;
|
||||
# 客户端保持连接时间
|
||||
keepalive_timeout 15;
|
||||
types_hash_max_size 2048;
|
||||
# 包含MIME类型的配置
|
||||
include /etc/nginx/mime.types;
|
||||
# 默认使用二进制流格式
|
||||
default_type application/octet-stream;
|
||||
# 包含其他配置文件
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
# 包含项目的Nginx配置文件
|
||||
include /root/project/conf/*.conf;
|
||||
}
|
||||
```
|
||||
|
||||
2. 编辑局部配置文件(`/root/project/conf/nginx.conf`)。
|
||||
|
||||
```Nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
access_log /root/project/logs/access.log;
|
||||
error_log /root/project/logs/error.log;
|
||||
location / {
|
||||
include uwsgi_params;
|
||||
uwsgi_pass 172.18.61.250:8000;
|
||||
}
|
||||
location /static/ {
|
||||
alias /root/project/src/fangall/static/;
|
||||
expires 30d;
|
||||
}
|
||||
}
|
||||
server {
|
||||
listen 443;
|
||||
server_name _;
|
||||
ssl on;
|
||||
access_log /root/project/logs/access.log;
|
||||
error_log /root/project/logs/error.log;
|
||||
ssl_certificate /root/project/conf/cert/214915882850706.pem;
|
||||
ssl_certificate_key /root/project/conf/cert/214915882850706.key;
|
||||
ssl_session_timeout 5m;
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_prefer_server_ciphers on;
|
||||
location / {
|
||||
include uwsgi_params;
|
||||
uwsgi_pass 172.18.61.250:8000;
|
||||
}
|
||||
location /static/ {
|
||||
alias /root/project/src/fangall/static/;
|
||||
expires 30d;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
到此为止,我们可以启动Nginx来访问我们的应用程序,HTTP和HTTPS都是没有问题的,如果Nginx已经运行,在修改配置文件后,我们可以用下面的命令重新启动Nginx。
|
||||
|
||||
3. 重启Nginx服务器。
|
||||
|
||||
```Shell
|
||||
nginx -s reload
|
||||
```
|
||||
|
||||
> 说明:可以对Django项目使用`python manage.py collectstatic`命令将静态资源收集到指定目录下,要做到这点只需要在项目的配置文件`settings.py`中添加`STATIC_ROOT`配置即可。
|
||||
|
||||
#### 负载均衡配置
|
||||
|
||||
下面的配置中我们使用Nginx实现负载均衡,为另外的三个Nginx服务器(通过Docker创建)提供反向代理服务。
|
||||
|
||||
```Shell
|
||||
docker run -d -p 801:80 --name nginx1 nginx:latest
|
||||
docker run -d -p 802:80 --name nginx2 nginx:latest
|
||||
docker run -d -p 803:80 --name nginx3 nginx:latest
|
||||
```
|
||||
|
||||
```Nginx
|
||||
user root;
|
||||
worker_processes auto;
|
||||
error_log /var/log/nginx/error.log;
|
||||
pid /run/nginx.pid;
|
||||
|
||||
include /usr/share/nginx/modules/*.conf;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
# 为HTTP服务配置负载均衡
|
||||
http {
|
||||
upstream fang.com {
|
||||
server 172.18.61.250:801 weight=4;
|
||||
server 172.18.61.250:802 weight=2;
|
||||
server 172.18.61.250:803 weight=2;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
|
||||
ssl on;
|
||||
access_log /root/project/logs/access.log;
|
||||
error_log /root/project/logs/error.log;
|
||||
ssl_certificate /root/project/conf/cert/214915882850706.pem;
|
||||
ssl_certificate_key /root/project/conf/cert/214915882850706.key;
|
||||
ssl_session_timeout 5m;
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_buffering off;
|
||||
proxy_pass http://fang.com;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 说明:Nginx在配置负载均衡时,默认使用WRR(加权轮询算法),除此之外还支持ip_hash、fair(需要安装upstream_fair模块)和url_hash算法。此外,在配置upstream模块时可以指定服务器的状态值,包括:backup(备份机器,其他服务器不可用时才将请求分配到该机器)、down、fail_timeout(请求失败达到max_fails后的暂停服务时间)、max_fails(允许请求失败的次数)和weight(轮询的权重)。
|
||||
|
||||
### Keepalived
|
||||
|
||||
当使用Nginx进行负载均衡配置时,要考虑负载均衡服务器宕机的情况。为此可以使用Keepalived来实现负载均衡主机和备机的热切换,从而保证系统的高可用性。Keepalived的配置还是比较复杂,通常由专门做运维的人进行配置,一个基本的配置可以参照[《Keepalived的配置和使用》](https://www.jianshu.com/p/dd93bc6d45f5)。
|
||||
|
||||
### MySQL主从复制
|
||||
|
||||
下面还是基于Docker来演示如何配置MySQL主从复制。我们事先准备好MySQL的配置文件以及保存MySQL数据和运行日志的目录,然后通过Docker的数据卷映射来指定容器的配置、数据和日志文件的位置。
|
||||
|
||||
```Shell
|
||||
root
|
||||
└── mysql
|
||||
├── conf
|
||||
│ ├── master
|
||||
│ │ └── mysqld.cnf
|
||||
│ ├── slave1
|
||||
│ │ └── mysqld.cnf
|
||||
│ ├── slave2
|
||||
│ │ └── mysqld.cnf
|
||||
│ └── slave3
|
||||
│ └── mysqld.cnf
|
||||
└── data
|
||||
├── master
|
||||
├── slave1
|
||||
├── slave2
|
||||
└── slave3
|
||||
```
|
||||
|
||||
1. MySQL的配置文件(master和slave的配置文件需要不同的server-id)。
|
||||
|
||||
```
|
||||
[mysqld]
|
||||
pid-file=/var/run/mysqld/mysqld.pid
|
||||
socket=/var/run/mysqld/mysqld.sock
|
||||
datadir=/var/lib/mysql
|
||||
log-error=/var/log/mysql/error.log
|
||||
server-id=1
|
||||
log_bin=/var/log/mysql/mysql-bin.log
|
||||
expire_logs_days=30
|
||||
max_binlog_size=256M
|
||||
symbolic-links=0
|
||||
```
|
||||
|
||||
2. 创建和配置master。
|
||||
|
||||
```Shell
|
||||
docker run -d -p 3306:3306 --name mysql57 \
|
||||
-v /root/mysql/conf/master:/etc/mysql/mysql.conf.d \
|
||||
-v /root/mysql/data/master:/var/lib/mysql \
|
||||
-e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
|
||||
docker exec -it mysql57 /bin/bash
|
||||
```
|
||||
|
||||
```Shell
|
||||
mysql -u root -p
|
||||
Enter password:
|
||||
Welcome to the MySQL monitor. Commands end with ; or \g.
|
||||
Your MySQL connection id is 1
|
||||
Server version: 5.7.23-log MySQL Community Server (GPL)
|
||||
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
Oracle is a registered trademark of Oracle Corporation and/or its
|
||||
affiliates. Other names may be trademarks of their respective
|
||||
owners.
|
||||
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
|
||||
|
||||
mysql> grant replication slave on *.* to 'slave'@'%' identified by 'iamslave';
|
||||
Query OK, 0 rows affected, 1 warning (0.00 sec)
|
||||
|
||||
mysql> flush privileges;
|
||||
Query OK, 0 rows affected (0.00 sec)
|
||||
|
||||
mysql> show master status;
|
||||
+------------------+----------+--------------+------------------+-------------------+
|
||||
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
|
||||
+------------------+----------+--------------+------------------+-------------------+
|
||||
| mysql-bin.000001 | 590 | | | |
|
||||
+------------------+----------+--------------+------------------+-------------------+
|
||||
1 row in set (0.00 sec)
|
||||
|
||||
mysql> quit
|
||||
Bye
|
||||
exit
|
||||
```
|
||||
|
||||
上面创建Docker容器时使用的`-v`参数(`--volume`)表示映射数据卷,冒号前是宿主机的目录,冒号后是容器中的目录,这样相当于将宿主机中的目录挂载到了容器中。
|
||||
|
||||
3. 创建和配置slave。
|
||||
|
||||
```Shell
|
||||
docker run -d -p 3307:3306 --name mysql57-slave-1 \
|
||||
-v /root/mysql/conf/slave1:/etc/mysql/mysql.conf.d \
|
||||
-v /root/mysql/data/slave1:/var/lib/mysql \
|
||||
-e MYSQL_ROOT_PASSWORD=123456 \
|
||||
--link mysql57:mysql57 mysql:5.7
|
||||
docker exec -it mysql57-slave-1 /bin/bash
|
||||
```
|
||||
|
||||
```Shell
|
||||
mysql -u root -p
|
||||
Enter password:
|
||||
Welcome to the MySQL monitor. Commands end with ; or \g.
|
||||
Your MySQL connection id is 2
|
||||
Server version: 5.7.23-log MySQL Community Server (GPL)
|
||||
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
Oracle is a registered trademark of Oracle Corporation and/or its
|
||||
affiliates. Other names may be trademarks of their respective
|
||||
owners.
|
||||
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
|
||||
|
||||
mysql> reset slave;
|
||||
Query OK, 0 rows affected (0.02 sec)
|
||||
|
||||
mysql> change master to master_host='mysql57', master_user='slave', master_password='iamslave', master_log_file='mysql-bin.000003', master_log_pos=590;
|
||||
Query OK, 0 rows affected, 2 warnings (0.03 sec)
|
||||
|
||||
mysql> start slave;
|
||||
Query OK, 0 rows affected (0.01 sec)
|
||||
|
||||
mysql> show slave status\G
|
||||
*************************** 1. row ***************************
|
||||
Slave_IO_State: Waiting for master to send event
|
||||
Master_Host: mysql57
|
||||
Master_User: slave
|
||||
Master_Port: 3306
|
||||
Connect_Retry: 60
|
||||
Master_Log_File: mysql-bin.000001
|
||||
Read_Master_Log_Pos: 590
|
||||
Relay_Log_File: f352f05eb9d0-relay-bin.000002
|
||||
Relay_Log_Pos: 320
|
||||
Relay_Master_Log_File: mysql-bin.000001
|
||||
Slave_IO_Running: Yes
|
||||
Slave_SQL_Running: Yes
|
||||
Replicate_Do_DB:
|
||||
Replicate_Ignore_DB:
|
||||
Replicate_Do_Table:
|
||||
Replicate_Ignore_Table:
|
||||
Replicate_Wild_Do_Table:
|
||||
Replicate_Wild_Ignore_Table:
|
||||
Last_Errno: 0
|
||||
Last_Error:
|
||||
Skip_Counter: 0
|
||||
Exec_Master_Log_Pos: 590
|
||||
Relay_Log_Space: 534
|
||||
Until_Condition: None
|
||||
Until_Log_File:
|
||||
Until_Log_Pos: 0
|
||||
Master_SSL_Allowed: No
|
||||
Master_SSL_CA_File:
|
||||
Master_SSL_CA_Path:
|
||||
Master_SSL_Cert:
|
||||
Master_SSL_Cipher:
|
||||
Master_SSL_Key:
|
||||
Seconds_Behind_Master: 0
|
||||
Master_SSL_Verify_Server_Cert: No
|
||||
Last_IO_Errno: 0
|
||||
Last_IO_Error:
|
||||
Last_SQL_Errno: 0
|
||||
Last_SQL_Error:
|
||||
Replicate_Ignore_Server_Ids:
|
||||
Master_Server_Id: 1
|
||||
Master_UUID: 30c38043-ada1-11e8-8fa1-0242ac110002
|
||||
Master_Info_File: /var/lib/mysql/master.info
|
||||
SQL_Delay: 0
|
||||
SQL_Remaining_Delay: NULL
|
||||
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
|
||||
Master_Retry_Count: 86400
|
||||
Master_Bind:
|
||||
Last_IO_Error_Timestamp:
|
||||
Last_SQL_Error_Timestamp:
|
||||
Master_SSL_Crl:
|
||||
Master_SSL_Crlpath:
|
||||
Retrieved_Gtid_Set:
|
||||
Executed_Gtid_Set:
|
||||
Auto_Position: 0
|
||||
Replicate_Rewrite_DB:
|
||||
Channel_Name:
|
||||
Master_TLS_Version:
|
||||
1 row in set (0.00 sec)
|
||||
|
||||
mysql> quit
|
||||
Bye
|
||||
exit
|
||||
```
|
||||
|
||||
接下来可以如法炮制配置出slave2和slave3,这样就可以搭建起一个“一主带三从”的主从复制环境。上面创建创建容器时使用的`--link`参数用来配置容器在网络上的主机名(网络地址别名),下一节有这个知识点的介绍。
|
||||
|
||||
### Docker
|
||||
|
||||
事实上,项目上线中最为麻烦的事情就是配置软件运行环境,环境的差异会给软件的安装和部署带来诸多的麻烦,而Docker正好可以解决这个问题。关于Docker在之前的文档中我们已经介绍过了,接下来我们对Docker的知识做一些必要的补充。
|
||||
|
||||
1. 创建镜像文件。
|
||||
|
||||
将容器保存成镜像:
|
||||
|
||||
```Shell
|
||||
docker commit -m "..." -a "..." <container-name> jackfrued/<image-name>
|
||||
```
|
||||
|
||||
使用Dockerfile构建镜像:
|
||||
|
||||
```Dockerfile
|
||||
# 指定基础镜像文件
|
||||
FROM centos:latest
|
||||
|
||||
# 指定维护者信息
|
||||
MAINTAINER jackfrued
|
||||
|
||||
# 执行命令
|
||||
RUN yum -y gcc
|
||||
RUN cd ~
|
||||
RUN mkdir -p project/src
|
||||
RUN mkdir -p project/logs
|
||||
|
||||
# 拷贝文件
|
||||
COPY ...
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE ...
|
||||
|
||||
# 在容器启动时执行命令
|
||||
CMD ~/init.sh
|
||||
```
|
||||
|
||||
```Shell
|
||||
docker build -t jackfrued/<image-name> .
|
||||
```
|
||||
|
||||
2. 镜像的导入和导出。
|
||||
|
||||
```Shell
|
||||
docker save -o <file-name>.tar <image-name>:<version>
|
||||
docker load -i <file-name>.tar
|
||||
```
|
||||
|
||||
3. 推送到DockerHub服务器。
|
||||
|
||||
```Shell
|
||||
docker tag <image-name>:<version> jackfrued/<name>
|
||||
docker login
|
||||
docker push jackfrued/<name>
|
||||
```
|
||||
|
||||
4. 容器之间的通信。
|
||||
|
||||
```Shell
|
||||
docker run --link <container-name>:<alias-name>
|
||||
```
|
||||
|
||||
|
||||
如果我们能够在Docker中完成项目的部署,并且将整个部署好的容器打包成镜像文件进行分发和安装,这样就可以解决项目在多个节点上进行部署时可能遇到的麻烦,而且整个部署可以在很短的时间内完成。
|
||||
|
||||
### Supervisor
|
||||
|
||||
[Supervisor](https://github.com/Supervisor/supervisor)是一个用Python写的进程管理工具,可以很方便的用来在类Unix系统下启动、重启(自动重启程序)和关闭进程。
|
||||
|
||||
1. 安装Supervisor。
|
||||
|
||||
```Shell
|
||||
yum -y install supervisor
|
||||
```
|
||||
|
||||
2. 查看Supervisor的配置文件。
|
||||
|
||||
```Shell
|
||||
vim /etc/supervisord.conf
|
||||
...
|
||||
[include]
|
||||
files = supervisord.d/*.ini
|
||||
```
|
||||
|
||||
可以看出自定义的管理配置代码可以放在`/etc/supervisord.d`目录中,并且文件名以`ini`作为后缀即可。
|
||||
|
||||
3. 编写管理配置代码。
|
||||
|
||||
```Shell
|
||||
cd /etc/supervisord.d
|
||||
vim fang.ini
|
||||
```
|
||||
|
||||
```INI
|
||||
[program:fang]
|
||||
...
|
||||
```
|
||||
|
||||
4. 启动Supervisor服务和查看状态。
|
||||
|
||||
```Shell
|
||||
systemctl start supervisord
|
||||
supervisorctl status
|
||||
```
|
||||
|
||||
### 其他服务
|
||||
|
||||
1. 常用开源软件。
|
||||
|
||||
| 功能 | 开源方案 |
|
||||
| ------------------- | ------------------------- |
|
||||
| 版本控制工具 | Git、Mercurial、SVN |
|
||||
| 缺陷管理 | Redmine、Mantis |
|
||||
| 负载均衡 | Nginx、LVS、HAProxy |
|
||||
| 邮件服务 | Postfix、Sendmail |
|
||||
| HTTP服务 | Nginx、Apache |
|
||||
| 消息队列 | RabbitMQ、ZeroMQ、Redis |
|
||||
| 文件系统 | FastDFS |
|
||||
| 基于位置服务(LBS) | MongoDB、Redis |
|
||||
| 监控服务 | Nagios、Zabbix |
|
||||
| 关系型数据库 | MySQL、PostgreSQL |
|
||||
| 非关系型数据库 | MongoDB、Redis、Cassandra |
|
||||
| 搜索引擎 | ElasticSearch、Solr |
|
||||
| 缓存服务 | Mamcached、Redis |
|
||||
|
||||
2. 常用云服务。
|
||||
|
||||
| 功能 | 可用的云服务 |
|
||||
| -------------- | --------------------------------------- |
|
||||
| 团队协作工具 | Teambition、钉钉 |
|
||||
| 代码托管平台 | Github、Gitee、CODING |
|
||||
| 邮件服务 | SendCloud |
|
||||
| 云存储(CDN) | 七牛、OSS、LeanCloud、Bmob、又拍云、AWS |
|
||||
| 移动端推送 | 极光、友盟、百度 |
|
||||
| 即时通信 | 环信、融云 |
|
||||
| 短信服务 | 云片、极光、Luosimao、又拍云 |
|
||||
| 第三方登录 | 友盟、ShareSDK |
|
||||
| 网站监控和统计 | 阿里云监控、监控宝、百度云观测、小鸟云 |
|
||||
|
189
README.md
|
@ -208,40 +208,22 @@
|
|||
|
||||
#### Day41 - [快速上手](./Day41-55/01.快速上手.md)
|
||||
|
||||
|
||||
|
||||
#### Day42 - [深入模型](./Day41-55/02.深入模型.md)
|
||||
|
||||
|
||||
|
||||
#### Day43 - [静态资源和Ajax请求](./Day41-55/03.静态资源和Ajax请求.md)
|
||||
|
||||
|
||||
|
||||
#### Day44 - [表单的应用](./Day41-55/04.表单的应用.md)
|
||||
|
||||
|
||||
|
||||
#### Day45 - [Cookie和会话](./Day41-55/05.Cookie和会话.md)
|
||||
|
||||
|
||||
|
||||
#### Day46 - [中间件的应用](./Day41-55/06.中间件的应用.md)
|
||||
|
||||
|
||||
|
||||
#### Day47 - [日志和缓存](./Day41-55/07.日志和缓存.md)
|
||||
|
||||
|
||||
|
||||
#### Day48 - [文件上传](./Day41-55/08.文件上传.md)
|
||||
|
||||
|
||||
|
||||
#### Day49-50 - [RESTful架构和应用](./Day41-55/09-10.RESTful架构和应用.md)
|
||||
|
||||
|
||||
|
||||
#### Day51-55 - [项目实战](./Day41-55/11-15.项目实战.md)
|
||||
|
||||
- 项目开发流程和相关工具
|
||||
|
@ -255,28 +237,16 @@
|
|||
|
||||
#### Day56 - [安装和入门](./Day56-65/01.安装和入门.md)
|
||||
|
||||
|
||||
|
||||
#### Day57 - [模板的使用](./Day56-65/02.模板的使用.md)
|
||||
|
||||
|
||||
|
||||
#### Day58 - [表单的处理](./Day56-65/03.表单的处理.md)
|
||||
|
||||
|
||||
|
||||
#### Day59 - [数据库操作](./Day56-65/04.数据库操作.md)
|
||||
|
||||
|
||||
|
||||
#### Day60 - [项目结构](./Day56-65/05.项目结构.md)
|
||||
|
||||
|
||||
|
||||
#### Day61-65 - [项目实战](./Day56-65/06-10.项目实战.md)
|
||||
|
||||
|
||||
|
||||
### Day66~75 - [爬虫开发](./Day66-75)
|
||||
|
||||
#### Day66 - [网络爬虫和相关工具](./Day66-75/01.网络爬虫和相关工具.md)
|
||||
|
@ -329,26 +299,143 @@
|
|||
|
||||
### Day91~100 - [团队项目开发](./Day91-100)
|
||||
|
||||
#### Day91 - [过程模型和团队开发工具](./Day91-100/过程模型和团队开发工具.md)
|
||||
|
||||
|
||||
|
||||
#### Day92 - [模块分割与单元测试](./Day91-100/模块分割与单元测试.md)
|
||||
|
||||
|
||||
|
||||
#### Day93~Day97 - [开发中的常见问题](./Day91-100/开发中的常见问题.md)
|
||||
|
||||
|
||||
|
||||
#### Day98 - [持续集成](./Day91-100/持续集成.md)
|
||||
|
||||
|
||||
|
||||
#### Day99 - [项目部署和安全性措施](./Day91-100/项目部署和安全性措施.md)
|
||||
|
||||
|
||||
|
||||
#### Day100 - [性能测试和性能调优](./Day91-100/性能测试和性能调优.md)
|
||||
#### 过程模型
|
||||
|
||||
1. 软件过程模型
|
||||
- 经典过程模型(瀑布模型)
|
||||
- 可行性分析(研究做还是不做),输出《可行性分析报告》。
|
||||
- 需求分析(研究做什么),输出《需求规格说明书》和产品界面原型图。
|
||||
- 概要设计和详细设计,输出概念模型图、物理模型图、类图、时序图等。
|
||||
- 编码 / 测试。
|
||||
- 上线 / 维护。
|
||||
- 敏捷开发(Scrum)- 产品所有者、Scrum Master、研发人员 - Sprint
|
||||
- 产品的Backlog(用户故事、产品原型)。
|
||||
- 计划会议(评估和预算)。
|
||||
- 日常开发(站立会议、番茄工作法、结对编程、测试先行、代码重构……)。
|
||||
- 修复bug(问题描述、重现步骤、测试人员、被指派人)。
|
||||
- 评审会议(Showcase)。
|
||||
- 回顾会议(当前周期做得好和不好的地方)。
|
||||
2. 项目团队组建
|
||||
- 团队的构成和角色
|
||||
|
||||
![company_architecture](./res/company_architecture.png)
|
||||
|
||||
- 编程规范和代码审查(flake8、pylint)
|
||||
|
||||
![](./res/pylint.png)
|
||||
|
||||
- Python中的一些“惯例”(请参考[《Python惯例-如何编写Pythonic的代码》](Python惯例-如何编写Pythonic的代码.md))
|
||||
3. 团队开发工具介绍
|
||||
- 版本控制:Git、Mercury
|
||||
- 缺陷管理:Github/Gitee、Redmine、禅道
|
||||
- 持续集成:Jenkins、Travis-CI
|
||||
|
||||
请参考[《团队项目开发》](团队项目开发.md)。
|
||||
|
||||
#### 项目选题和理解业务
|
||||
|
||||
1. 选题范围设定
|
||||
|
||||
- CMS(用户端):新闻聚合网站、问答/分享社区、影评/书评网站等。
|
||||
- MIS(用户端+管理端):KMS、KPI考核系统、HRS、仓储管理系统等。
|
||||
|
||||
- App后台(管理端+数据接口):二手交易类App、报刊杂志类App、健康健美类App、旅游类App、社交类App、阅读类App等。
|
||||
- 其他类型:自身行业背景和工作经验、业务容易理解和把控。
|
||||
|
||||
2. 需求理解、模块划分和任务分配
|
||||
|
||||
- 需求理解:头脑风暴和竞品分析。
|
||||
- 模块划分:画思维导图(XMind),每个模块是一个枝节点,每个具体的功能是一个叶节点(用动词表述),需要确保每个叶节点无法再生出新节点,确定每个叶子节点的重要性、优先级和工作量。
|
||||
- 任务分配:由项目负责人根据上面的指标为每个团队成员分配任务。
|
||||
|
||||
![](./res/requirements_by_xmind.png)
|
||||
|
||||
3. 制定项目进度表(每日更新)
|
||||
|
||||
| 模块 | 功能 | 人员 | 状态 | 完成 | 工时 | 计划开始 | 实际开始 | 计划结束 | 实际结束 | 备注 |
|
||||
| ---- | -------- | ------ | -------- | ---- | ---- | -------- | -------- | -------- | -------- | ---------------- |
|
||||
| 评论 | 添加评论 | 王大锤 | 正在进行 | 50% | 4 | 2018/8/7 | | 2018/8/7 | | |
|
||||
| | 删除评论 | 王大锤 | 等待 | 0% | 2 | 2018/8/7 | | 2018/8/7 | | |
|
||||
| | 查看评论 | 白元芳 | 正在进行 | 20% | 4 | 2018/8/7 | | 2018/8/7 | | 需要进行代码审查 |
|
||||
| | 评论投票 | 白元芳 | 等待 | 0% | 4 | 2018/8/8 | | 2018/8/8 | | |
|
||||
|
||||
#### 概念模型和正向工程
|
||||
|
||||
1. UML和E-R图
|
||||
|
||||
![uml](./res/uml-graph.png)
|
||||
|
||||
2. 通过模型创建表(正向工程)
|
||||
|
||||
```Shell
|
||||
python manage.py makemigrations app
|
||||
python manage.py migrate
|
||||
```
|
||||
|
||||
#### 物理模型和反向工程
|
||||
|
||||
1. PowerDesigner
|
||||
|
||||
![](./res/power-designer-pdm.png)
|
||||
|
||||
2. 通过数据表创建模型
|
||||
|
||||
```Shell
|
||||
python manage.py inspectdb > app/models.py
|
||||
```
|
||||
|
||||
#### 项目开发中的公共问题
|
||||
|
||||
1. 数据的配置
|
||||
2. 缓存的配置
|
||||
3. 日志的配置
|
||||
4. Django的使用技巧
|
||||
5. 好用的Python模块(图像处理、数据加密、三方API)
|
||||
|
||||
### REST API设计
|
||||
|
||||
1. RESTful架构
|
||||
2. API接口文档的撰写([《网络API接口设计》](网络API接口设计.md))
|
||||
3. Django-REST-Framework的应用
|
||||
|
||||
#### 项目中的重点难点剖析
|
||||
|
||||
1. 使用缓存缓解数据库压力(Redis)
|
||||
2. 使用消息队列缓解服务器压力(Celery + RabbitMQ)
|
||||
|
||||
#### 单元测试
|
||||
|
||||
1. 测试的种类
|
||||
2. 编写单元测试(unitest、TestCase)
|
||||
3. 测试覆盖率(Coverage)
|
||||
|
||||
#### 项目部署
|
||||
|
||||
1. 部署前的准备工作
|
||||
- 关键设置(SECRET_KEY / DEBUG / ALLOWED_HOSTS / 缓存 / 数据库)
|
||||
- HTTPS / CSRF_COOKIE_SECUR / SESSION_COOKIE_SECURE
|
||||
- 日志相关配置
|
||||
2. Linux常用命令回顾
|
||||
3. Linux常用服务的安装和配置
|
||||
4. uWSGI和Nginx的使用
|
||||
5. 虚拟化容器(Docker)
|
||||
|
||||
#### 性能测试
|
||||
|
||||
1. AB的使用
|
||||
2. SQLslap的使用
|
||||
3. sysbench的使用
|
||||
|
||||
#### 自动化测试
|
||||
|
||||
1. 使用Shell和Python进行自动化测试
|
||||
2. 使用Selenium实现自动化测试
|
||||
3. 测试工具Robot Framework介绍
|
||||
|
||||
#### 项目性能调优
|
||||
|
||||
1. 数据库性能调优
|
||||
2. 代码性能调优
|
||||
3. 静态文件服务器和CDN加速
|
||||
|
||||
|
||||
|
|
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 110 KiB |
After Width: | Height: | Size: 113 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 184 KiB |
After Width: | Height: | Size: 313 KiB |
After Width: | Height: | Size: 195 KiB |
After Width: | Height: | Size: 209 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 140 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 400 KiB |
After Width: | Height: | Size: 218 KiB |
After Width: | Height: | Size: 290 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 104 KiB |
After Width: | Height: | Size: 253 KiB |
After Width: | Height: | Size: 142 KiB |
After Width: | Height: | Size: 158 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 133 KiB |
After Width: | Height: | Size: 147 KiB |
After Width: | Height: | Size: 189 KiB |
After Width: | Height: | Size: 178 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 1.0 MiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 296 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 726 KiB |
After Width: | Height: | Size: 345 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 298 KiB |
After Width: | Height: | Size: 212 KiB |
After Width: | Height: | Size: 238 KiB |
After Width: | Height: | Size: 212 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 146 KiB |
After Width: | Height: | Size: 439 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 174 KiB |
After Width: | Height: | Size: 48 KiB |