系统分析个人大作业总结

在这一次的大作业中,我做的工作总的来说包括了服务端的部署,服务端框架的搭建,api的设计,还有安卓前端的编码。不仅接触使用了之前不了解的技术,对之前学过的技术也有了进一步的加深。

PSP2.1 统计表

PSP阶段 耗时(%)
计划 20
确定项目范围 10
预估工作量和时间 5
任务分工 5
开发 70
分析需求 5
生成设计文档 5
设计复审 5
代码规范 5
具体设计 5
具体编码 30
代码复审 5
测试 10
报告 10
测试报告 3
计算工作量 2
事后总结,提出过程改进计划 5
合计 100

个人git总结

  • sysuz4.github.com 文档

系统分析个人大作业总结_第1张图片

  • EarningMoney 易闲圈前端

系统分析个人大作业总结_第2张图片

  • AppServer 易闲圈后端

系统分析个人大作业总结_第3张图片

个人博客

  • docker和jenkins自动构建
  • 还有本篇博客

特别致谢

  • 郑先淇同学,作为项目经理,总能按照大家的能力够分好大家的工作并且督促大家完成;
  • 朱泽磊同学,后端开发的主力,任劳任怨,事无巨细地满足前端开发人员的需求;
  • 钟朝晖同学,前端开发的主力,项目初期一个人扛起了android开发的大旗;
  • 张寅哲同学,独立完成数据库表的设计,在项目进度吃紧的时候总能赶在DDL前完成任务;
  • 赵米同学:作为标准的制定和文档的编写人,米哥打在屏幕上的内容就是我们要遵守的标准

个人各部分工作总结

在这一次的大作业中,我做的工作总的来说包括了服务端的部署,服务端框架的搭建,api的设计,还有安卓前端的编码。不仅接触使用了之前不了解的技术,对之前学过的技术也有了进一步的加深。

服务端搭建

api设计与展示

我们的api设计用到的是restful风格的api。进行交互展示用到的是swagger。

restful

  1. Version your API:规范的API应该包含版本信息,在RESTful API中,最简单的包含版本的方法是将版本信息放到url中,如:/api/v1/posts/
    (另一种优雅的做法是,使用HTTP header中的accept来传递版本信息,这也是GitHub API 采取的策略)
  2. Use nouns, not verbs :RESTful API 中的url是指向资源的,而不是描述行为的,因此设计API时,应使用名词而非动词来描述语义,否则会引起混淆和语义不清
  3. GET and HEAD should always be safe: RFC2616已经明确指出,GET和HEAD方法必须始终是安全的。例如,有这样一个不规范的API:
    The following api is used to delete articles
    [GET]
    /api/deleteArticle?id=1
    试想,如果搜索引擎访问了上面url会如何?
  4. Nested resources routing: 如果要获取一个资源子集,采用 nested routing 是一个优雅的方式,如,列出所有文章中属于Gevin编写的文章:
    List Gevin’s articles
    /api/authors/gevin/articles/
  5. Filter: 对于资源集合,可以通过url参数对资源进行过滤,如:
    List Gevin’s articles
    /api/articles?author=gevin
    分页就是一种最典型的资源过滤。
  6. Pagination: 对于资源集合,分页获取是一种比较合理的方式。如果基于开发框架(如Django REST Framework),直接使用开发框架中的分页机制即可,如果是自己实现分页机制,Gevin的策略是:
    返回资源集合是,包含与分页有关的数据如下:
    {
    “page”: 1, # 当前是第几页
    “pages”: 3, # 总共多少页
    “per_page”: 10, # 每页多少数据
    “has_next”: true, # 是否有下一页数据
    “has_prev”: false, # 是否有前一页数据
    “total”: 27 # 总共多少数据
    }
    当想API请求资源集合时,可选的分页参数为:
    page 当前是第几页,默认为1
    per_page 每页多少条记录,默认为系统默认值
    另外,系统内还设置一个per_page_max字段,用于标记系统允许的每页最大记录数,当per_page值大于 per_page_max 值时,每页记录条数为 per_page_max。
  7. Url design tricks:
    (1)Url是区分大小写的
    (2)Back forward Slash (/):通常建议url以/作为结尾
    (3)连接符 - 和 下划线 _:RESTful API 应具备良好的可读性,当url中某一个片段(segment)由多个单词组成时,建议使用 - 来隔断单词,而不是使用 _

swagger

https://blog.csdn.net/canot/article/details/55051346

  • Swagger Editor: Swagger提供的一个编辑器,用来通过Swagger提供的特定的YAML语法来编写API文档
  • Swagger Codegen: 代码生成器
  • Swagger UI: YAML语法定义我们的RESTful API,然后它会自动生成一篇排版优美的API文档,并且提供实时预览

主要是采用swagger Editor来编写我们设计的restful api,定义不同url对应的行为,发送和接收的model,状态码等不同的情况,主要用的是json和yaml,具体的语法可参考上述链接中的例子

服务端搭建

主要采用的是springboot,主要是对spring的一些原有框架进行了整合,减少了繁琐的配置,同时又有相对成熟的体系,很多功能无需自己实现。

springboot

https://blog.csdn.net/qq_35571554/article/details/82184122
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。
简单的来说就是,只需几个jar和一些简单的配置,就可以快速开发项目。

1、用IDEA开始搭建一个Springboot项目
系统分析个人大作业总结_第4张图片

2、点击next,填写项目包的一些信息

系统分析个人大作业总结_第5张图片

3、选中打钩的地方
系统分析个人大作业总结_第6张图片

系统分析个人大作业总结_第7张图片

系统分析个人大作业总结_第8张图片

4、由上图可知,java是存放业务代码,现在com.xz.blog包下除了启动类,其余都是空的,需要我们来添加controller、mapper、model、service等包;resources是存放项目资源,templates放置模板(页面)。推荐使用thymeleaf,也可以集成Jsp,static放置静态资源。js,images等。
系统分析个人大作业总结_第9张图片

由于我此时实现的服务端主要是rest风格的api,所以不需要处理前端的网页静态文件的请求和渲染。
简单的说一下总体的结构,我们通过上述步骤创建成功项目以后,并创建上述对应的文件夹,基本的项目结构就已经成型了。
(1)pom.xml中主要是依赖文件,maven构建项目的时候就要从这个文件中读取项目相关的依赖。在创建项目时勾选的已经默认帮我们把依赖写好在了这里,如果我们在项目编码过程中发现还需要一些第三方的依赖,则可以添加在这里。
(2)appllication.properties:这个文件中主要填写的是一些配置信息,比如说mybaties连接的数据库名,密码,model类存放的包名;redis连接的用户名和密码等都是在这里设置的。
(3)源代码:
• Controller:控制层,处理HTTP请求,收集参数,检查参数类型和合法性,并调用相应的Service
• Service:服务层,处理业务逻辑
• mapper:处理数据库的交互
• Model:数据层,数据模型

简单的说,我们可以认为,controller中是处理不同的url的,对于restful的api来说,我们可以在controller中为每个资源定义一个类处理相关的CRUD请求,而Service则是处理业务逻辑,和Controller并没有必然的对应关系,可以在一个controller中调用多个service,主要取决与业务的模块划分,mapper中主要是数据库的交互mysql语句,对不同的model有不同的mysql语句。而model则对应着数据库中的表。

具体的代码可参考上述链接或我们的github地址
https://github.com/sysuz4/AppServer

JWT token

http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html

JWT可以说是一种token的规范,由于session在集群服务器时使用不太方便,所以就有了token的产生。

JWT风格的token主要由三部分组成
系统分析个人大作业总结_第10张图片

(1)header:Header 部分是一个 JSON 对象,描述 JWT 的元数据,包括像签名部分所用的算法和token的类型

{
  "alg": "HS256",
  "typ": "JWT"
}

上面代码中,alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。
最后,将上面的 JSON 对象使用 Base64URL 算法(详见后文)转成字符串。

(2)payload:Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用

iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号

当然,也可以自己定义一些字段来发送信息,注意,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。
最后,这个 JSON 对象也要使用 Base64URL 算法转成字符串。

(3)signature:Signature 部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。

客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。然后服务端收到token以后首先用相同的算法进行签名,检测有无篡改,然后用base64进行解码,取出payload中的信息进行授权验证,得到用户信息和判断是否token已经过期。

这样最大的好处就是在服务端无需对token进行存储,只需要用相同的签名算法则可以进行验证,这样在多个集群服务器上时就避免了同步的问题。

服务端部署

部署主要用到了docker,jenkins,nginx等技术

自动构建github并部署到服务器上可以参考我的这篇文章
https://blog.csdn.net/Artemis16340304/article/details/90679931

至于nginx,当然也可以用docker来进行容器化的安装,然后就是对nginx进行配置,达到静态服务器,分布式集群,反向代理等的目的

以下是nginx的一个docker安装教程
https://blog.csdn.net/wugenqiang/article/details/86513257

然后主要的工作是在与nginx配置文件的编写,简单的功能说明与配置如下
https://www.cnblogs.com/jimmy-muyuan/p/5424329.html

1、静态HTTP服务器
首先,Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML、图片)通过HTTP协议展现给客户端。

配置:

  server {
    listen 80; # 端口号
    location / {
        root /usr/share/nginx/html; # 静态文件路径
    }
}

2、反向代理服务器
客户端本来可以直接通过HTTP协议访问某网站应用服务器,网站管理员可以在中间加上一个Nginx,客户端请求Nginx,Nginx请求应用服务器,然后将结果返回给客户端,此时Nginx就是反向代理服务器。
系统分析个人大作业总结_第11张图片

server {
    listen 80;
    location / {
        proxy_pass http://192.168.20.1:8080; # 应用服务器HTTP地址
    }
}

既然服务器可以直接HTTP访问,为什么要在中间加上一个反向代理,不是多此一举吗?反向代理有什么作用?继续往下看,下面的负载均衡、虚拟主机等,都基于反向代理实现,当然反向代理的功能也不仅仅是这些。

3、负载均衡

当网站访问量非常大,网站站长开心赚钱的同时,也摊上事儿了。因为网站越来越慢,一台服务器已经不够用了。于是将同一个应用部署在多台服务器上,将大量用户的请求分配给多台机器处理。同时带来的好处是,其中一台服务器万一挂了,只要还有其他服务器正常运行,就不会影响用户使用。

Nginx可以通过反向代理来实现负载均衡。

系统分析个人大作业总结_第12张图片

upstream myapp {
    server 192.168.20.1:8080; # 应用服务器1
    server 192.168.20.2:8080; # 应用服务器2
}
server {
    listen 80;
    location / {
        proxy_pass http://myapp;
    }
}

以上配置会将请求轮询分配到应用服务器,也就是一个客户端的多次请求,有可能会由多台不同的服务器处理。可以通过ip-hash的方式,根据客户端ip地址的hash值将请求分配给固定的某一个服务器处理。

upstream myapp {
    ip_hash; # 根据客户端IP地址Hash值将请求分配给固定的一个服务器处理
    server 192.168.20.1:8080;
    server 192.168.20.2:8080;
}
server {
    listen 80;
    location / {
        proxy_pass http://myapp;
    }
}

另外,服务器的硬件配置可能有好有差,想把大部分请求分配给好的服务器,把少量请求分配给差的服务器,可以通过weight来控制。

 upstream myapp {
    server 192.168.20.1:8080 weight=3; # 该服务器处理3/4请求
    server 192.168.20.2:8080; # weight默认为1,该服务器处理1/4请求
}
server {
    listen 80;
    location / {
        proxy_pass http://myapp;
    }
}

4、虚拟主机

有的网站访问量大,需要负载均衡。然而并不是所有网站都如此出色,有的网站,由于访问量太小,需要节省成本,将多个网站部署在同一台服务器上。

例如将www.jim.com和www.tim.com两个网站部署在同一台服务器上,两个域名解析到同一个IP地址,但是用户通过两个域名却可以打开两个完全不同的网站,互相不影响,就像访问两个服务器一样,所以叫两个虚拟主机。

配置:

server {
    listen 80 default_server;
    server_name _;
    return 444; # 过滤其他域名的请求,返回444状态码
}
server {
    listen 80;
    server_name www.jim.com; # www.jim.com域名
    location / {
        proxy_pass http://localhost:8080; # 对应端口号8080
    }
}
server {
    listen 80;
    server_name www.tim.com; # www.tim.com域名
    location / {
        proxy_pass http://localhost:8081; # 对应端口号8081
    }
}

在服务器8080和8081分别开了一个应用,客户端通过不同的域名访问,根据server_name可以反向代理到对应的应用服务器。

虚拟主机的原理是通过HTTP请求头中的Host是否匹配server_name来实现的,有兴趣的同学可以研究一下HTTP协议。

另外,server_name配置还可以过滤有人恶意将某些域名指向你的主机服务器。

除此之外,nginx中loaction的编写与匹配也是一门学问

https://www.cnblogs.com/lidabo/p/4169396.html
https://www.jianshu.com/p/d3fb148cb5eb

安卓前端

安卓前端的话,这次作业主要的收获就是学会了用别人的写好的控件,作为依赖添加到我们的页面中,不用自己从头从官方的基本控件开始实现

https://github.com/wasabeef/awesome-android-ui

同时也回顾了当初学安卓的时候的知识,以下是当时不同功能作业的报告地址
https://gitee.com/Artemis_lin/projects

你可能感兴趣的:(作业)