大家好,我们是来自华中赛区的NCHU_文体两开花团队,意在文娱与体育,两面皆开花。
一、开篇
在路上,开着导航,副驾驶吐槽司机:“你又开错路了!路口慢点,赶紧找地方还车!”
在饭店,老师诧异着:“他们俩怎么还没过来?啥?你们租车去玩的?”
这就是我们在长沙最后一天的缩影——一群富有朝气的年轻人和两位负责的老师,喜悦地享受着长沙之行的尾巴。
我们是开心的,也是痛苦的。不过,好的是先经历了痛苦,后品尝了快乐。时光拉回到比赛前一天的晚上,为了使现场演示和答辩达到更好的效果,团队全体准备到凌晨3点,从一次次的排练,到PPT版本的兼容性,每一个细节,都尽心准备着。多少个日夜的辛苦,最终成就了我们的故事。
从南昌到长沙的一路走来,我们成长着、蜕变着。其中点点滴滴,心路历程,技术经验,无不是我们想要分享的。
二、源起,Attack!足球!
为什么是Attack 足球?最初的Attack 足球,本是为南昌航空大学软件学院足球队能更好的在比赛中发挥而定做的。“我们不仅是足球队的一员,还是软件学院的一名学生,具有得天独厚的优势。如果将足球战术板与软件结合到一起,会碰撞出怎样奇妙的火花呢?”这句话,是我们在 《【征文大学篇】Attack!足球!》 对Attack 足球的一段描述。
软件学院足球队,在战术讲解方面遇到了多种问题,我们本希望开发一款小程序,帮助其解决这些困难。但随着对产品的深入理解,不禁反问自己,既然软件足球队有使用战术板的不便,那么其他球队有没有这种不便呢?能不能做一款普适大众的 APP,让更多有需求的校园球队,享受Attack 足球带来的便利呢?
三、市场分析,产品定位
要从哪几个方面去分析一个产品呢?在所做的工作中,我们选取了市场调研、应用场景、用户三个角度为大家进行分析,希望我们的思路能对大家有帮助。
既然有了方向,便要付出行动。经过研究调查,2019年7月23日教育部发布的《全国青少年校园足球工作报告》中指出,五年来参加小学、初中、高中、大学四级联赛学生__共计1255万人次__,有3万多名省(区、市)级最佳阵容的学生参加全国夏(冬)令营活动。“经过过去五年的努力,我们现在已经在全国38万所中小学中遴选认定__校园足球特色学校____24126____所__,设立校园足球改革试验区38个,遴选校园足球试点县(区)135个,在全国布局建设‘满天星’训练营47个。”教育部体育卫生与艺术__教育司司长王登峰__说。
校园足球目前主要集中在小、初、高、大学的校园四级联赛中,本就拥有大量的用户基数。且前有“一带一路”国际青少年足球邀请赛,后有《全国青少年校园足球工作报告》,国家政策的支持,意味着校园足球的发展前景广阔,越来越多的人会接触足球,这个群体也会愈加庞大。
有潜在用户群体,就会有市场,而Attack 足球能否在其中抓住一丝机会呢?
从应用场景分析,战术板的使用场景可以分为三个阶段:
(1)赛前的战术布置;
(2)赛中的战术调整;
(3)赛后的复盘分析。
显然 Attack 足球战术板不适用于赛中的战术调整阶段,因为大部分赛中的战术调整更多是临场发挥,管理人员再利用手机去调整录音发布安排效果不佳。以此为导向,Attack 足球的使用场景应集中在赛前及赛后的两个阶段。
从用户角度分析,谁才是Attack 足球的真正终端用户?教练/队长还是队员?To B or To C,这是一个问题。就目前看,教练/队长是管理和发布战术安排的用户,队员是查阅战术的用户,那么产品主要功能聚焦在数量较少的管理人员身上,是否会对用户量有实际上的影响。考虑目前国内的情况,教练员也未必是能够对足球理念和知识通透的管理者,小初高联赛中有条件的球队能够配备专业或者具备足球知识基础的教练进行指导训练,但还有大部分条件不够的球队是其他科老师进行兼职,该问题现象在大学阶段尤其显著,非校队或专业队员获得专业指导的机会少之又少。Attack 足球的问题在于,工具有了,谁来更好的使用工具。
因此,为什么一定要局限于教练/队长讲授战术的情景呢?如果能解决教与练的问题,Attack 足球__战术板、战术安排、球队管理__将是符合目前用户需求的一个有利导向工具,在减轻教练在绘制战术时的负担的同时,也能给予缺少专业教练球队队员获取优秀战术的机会。至此,我们将Attack 足球的产品定位定为__高效、便捷提高校园足球战术素养的工具__,旨在__提高足球比赛赛前及赛后的两个阶段,教练讲授战术和队员学习、吸收战术的效率__。
四、设计理念,足球文化
学习前人的优秀设计,总结自身的独特特点。设计大师Dieter Rams:十条优秀设计准则。足球文化:独特的设计理念。
产品定位有了,现在如何设计出一款超出用户体验预期,能够给用户带来长期价值的产品是关键。设计大师Dieter Rams曾总结出十条优秀的设计准则,我们对其进行了揣摩与解读,整理出符合Attack 足球的要点,并将其作为指导我们产品设计的准则。
Good design is innovative 与 Good design makes a product useful.
Attack 足球作为一款工具类小程序,实用是基本属性。当然,创新也是Attack 足球的重要特点。Attack 足球除可以利用战术板功能__绘制战术__外,还能对__战术进行保存,反复观看__,解决了传统战术板零件携带不方便、零件易掉落,无法保存讲解战术的缺点;同时,它对应用场景进行了深度扩展,拥有__实时演练__功能,除用手机观看外,还可以__利用____PC____,现场投影__,供球队聚集在室内讲解战术。
Good design is aesthetic 与 Good design helps a product be understood.
![](https://image.wxopen.club/content_9ef120f0-2ec1-11ea-bb76-a0999b08aadb.png)
如上图4-1,在UI设计方面,我们在不断的改进。Attack 足球经历了__从最初的功能堆叠,到目前的结构清晰,再到即将发布的追求设计美感__几个阶段。__席克定律指出:面对更多选择,人们需要更多时间做出选择__。某些情况下,需要花费的时间太长了,以至于他们根本做不出决定,因为决定的负担太沉重。在Attack 足球Version 1.0中,我们将所有功能铺开,用户进入小程序后很容易陷入选择的困境。而Version 2.0中,我们将功能模块化展示,__界面也符合用户习惯的阅读模式——____F____模式__。在Version 3.0中,保留了V2.0中功能模块及其布局,同时新增了功能战术库。为了不将功能杂糅在一个页面,给用户一个快速的选择反应,我们重新设计了界面,应用了导航栏,导航栏精简成三个,分别是战术板、战术库、我的。由V 2.0过渡到现在的V 3.0,我们将战术板与球队管理的功能分离,使导航栏的指向性更加明确。
Attack 足球不仅为第一次进入的用户__精心准备了引导页__,而且__按功能模块划分了界面__,使用户在不同场景下明确知道使用哪个功能模块,做到了“__让产品不言自明__”。
Good design is thorough to the last detail
Attack 足球在每一个细节方面,都用心去思考,用心去打磨,这里举3个例子供大家参考。
(1)以引导页为例,在目前的版本中,我们的引导页只能通过点击下一步进行引导,通过思考,我们认为这是对用户不友好的。在即将推出的版本中,我们__取消了这种强迫式设计__,在引导页中增加了跳过与单击其他部位也可进入下一页功能。
![](https://image.wxopen.club/content_9f067f36-2ec1-11ea-bb76-a0999b08aadb.png)
(2)以我的球队页面为例,如上图4-2所示,Attack 足球使用了__去线条化__的方式,搭配__卡片式设计__,让页面看起来更加层次分明,干净利落。同时利用__统一间距或符合五分原则、黄金比例__的间距留白,区分信息的内容,将相互关联、相同或同类的内容放在一起, 使其形成一个视觉单元而不再是一个孤立的元素。这些细节的设计都是更好的帮助内容信息反馈的一种视觉形式,有助于组织信息、减少混乱、为用户提供清晰的结构。
(3)在Attack 足球战术板的功能中,之前的箭头有方向不确定的Bug,为了给用户更好的体验,我们的用心打磨,__通过数学分析,目前已经解决该Bug__,这个问题在下文的技术板块中也会提及。
除了吸收他人优秀的经验,我们也有__属于自己的独特设计理念__——将足球文化融入小程序的设计当中。如图,在初始使用界面,采用2.5D风格插画,模拟红蓝双方对垒,带来足球场的立体感。配色与图标方面,Attack 足球采用__足球场的绿色作为主色调,搭配红牌黄牌的颜色__,使用灰绿搭配的图标,整个画面更加明快活泼,简单大方而又不落俗套。如图,在Version 3.0 的首页,我们__融入了更多的足球元素__,如插画中的冠军杯、记分牌、战术板、足球、角旗杆等,并准备精心绘制每个省份的地方特色,比如天河足球场,希望__给广大的足球爱好者以亲切感__。
五、技术支撑,细节体现
在Attack 足球从idea变为现实的过程中,我们也遇到了很多技术难点。这里选取几个讲述,希望大家遇到相似的问题时,这些思路能够有些许帮助。
当我们的设计成型,就需要开发人员来实现了。好的产品背后必然有技术支撑,Attack 足球也不例外。我们采用分布式,基于微服务,将不同的功能部署到多个服务器中。图5-1是我们的系统总体架构。
下面我们将从分布式__服务注册发现、安全性、服务部署__三个方面大致阐述一下。在阐述之前,先为大家讲述一下相关知识。
__微服务__是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。
__分布式__是将系统独立分布在不同的物理机上面,其各个系统之间依赖网络来进行通信。在通信过程中处理繁多的服务器的主机与端口号、版本号、通信协议就是一个繁琐的过程,并且由于网络的隔离性,服务的状态并不能实时的被其他服务所发现。
因为分布式通信的繁琐性,我们在系统中引入了注册发现服务Eureka来实现以下功能。
- 服务注册:其构建一个注册中心,每个服务单元向注册中心登记自己提供的服务,将主机与端口号、版本号、通信协议告知注册中心,并为其配置相应的服务名。
- 服务发现:服务之间的调用不再通过IP或者Host来进行调用,而是通过其所分配的服务名来进行调用。
- 心跳机制:客户端将心跳发送到Eureka服务器,让服务器了解其状态,进而更新其注册中心的服务清单。
通过使用Eureka,我们将各个独立的服务注册到其上,共同组成一个分布式系统。
分布式系统不像单体系统,只需开放所需开放的端口,就可以保障系统一定的封闭性与安全性。因为资源有限,我们只能采用多个云服务器来实现。无法通过构建内网,来确保系统内部的安全性,基础服务实例的相关端口也不可避免的向公网暴露,此举带来了极大的安全隐患。
如图5-2我们开启服务端Centos的Firewall服务。Firewall 能将不同的网络连接归类到不同的信任级别。将其自身的公网IP归类到trusted zone (信任所有连接)。将其他于其有通信需求的服务器IP添加到public zone(允许指定的进入连接),然后将其所需通信的端口与其自身的IP配置成rich rules来允许请求通过。
这样公网只能访问到我们对外开放的两个433端口,我们只需对这两个端口的请求进行权限验证,就可以确保系统的安全性。在分布式架构中,传统的单体Session认证方案已经不能满足现有系统的需求。其服务独立分布在不同的服务器中,并且HTTP是无状态的。
传统的解决方案有以下两种:
- 使用共享Session机制。通过使用共享的Session缓存,各个服务的可以通过这个缓存获取的Session来进行认证,用户的权限信息保存在服务端,当系统的权限机制做出改变,可以灵活的对其进行修改
- 使用Token验证,将权限信息交由客户端来保存,可以减轻服务端的存储压力。每一次服务通过解析Token来验证用户的权限,需要合理设计加密机制,避免用户通过恶意更改Token来非法访问。
通过对上述两种机制的学习,我们为客户端__产生唯一的身份标识符__。用户的权限信息保存在Redis中,通过与客户端的身份标识符映射来确认用户的权限。这个技术方案提高了用户认证鉴定权限的效率,避免了大量的数据库和缓存查询。但是,这种方案的存在太大的性能开销,随着学习的深入,我们会在不久的将来采用__JWT+ Refresh Token__的方案对系统进行重构。
在最后的服务部署阶段。云服务器的带宽上限为5M,因此如果采用唯一的服务器来反向代理、路由处理,业务的性能上限将被这唯一的流量入口所限制。
如图5-3我们通过取消设立专门的路由服务器,直接将业务分为两块。用户直接访问两大业务服务器。将流量入口重定向为这两大业务服务器,可以在一定程度上降低服务带宽的限制。进一步将这两个业务的基础服务分别部署在不同的物理机上,可以在充分利用服务器的硬件资源和节省网络带宽开销中寻找一个平衡点。
以上内容阐述了我们在架构微服务分布式后台架构时所面临的问题,通过使用这个架构我们将后台的服务解耦成了两大块业务,极大的提高了服务的灵活性。通过使用Fegin组件的服务端负载均衡功能,在一定程度上提高了业务的性能上限。
因个人才疏学浅以及对于微服务架构的理解不够透彻,内容中如有错误,敬请斧正。通过此次比赛,将个人所学的相关理论知识第一次应用到产品中。其中也走了不少弯路、错路,无论如何都是一次宝贵的经验。后续我们将会投了更多的精力去学习。
在产品的前端方面,如图5-4,初期版本存在一个极大影响了用户的使用体验的地方。那就是之前提到过的箭头方向问题——如何根据用户随意画的一条曲线,在这条曲线末尾加上正确方向的箭头。
如何优化箭头的方向,给用户更好的体验呢?在Attack 足球中绘制的线条是一条不规则的曲线,描述一条不规则的曲线是比较难的,进而__要判断这条不规则曲线的走向、根据走向添加箭头的方向是更加困难的。__
首先,由图5-5可知,可以在一条曲线中取样若干离散的点来对这条曲线进行拟合,因此曲线的特征可以近似通过这些离散点序列来描述。每一条曲线都可以得到一个离散点的序列:
其中 L 表示由这条曲线取样得到的离散点序列,(x_n,y_n )表示曲线最终点坐标。
将连续的曲线转化为离散点的序列,我们便可以根据这个序列来确定曲线的特征。故可以选取序列中最后两个点坐标来近似描述曲线的方向,即有方向向量:
已知曲线终点方向向量,再由曲线终点坐标便可以确定箭头的位置和方向。
由图5-6可知,箭头可以由三个点C,D,E,两条向量(CD) ⃗,(ED) ⃗ ((CD) ⃗代表向量CD,下同)来确定,我们假定向量(CD) ⃗与(ED) ⃗的夹角,即箭头的夹角为90度。已知曲线的方向向量(AB) ⃗与x轴夹角为θ,便可以确定(CD) ⃗与x轴夹角为θ+45°,(ED) ⃗与x轴夹角θ-45°,曲线终点作为D点从而确定箭头的方向与位置。
在设计的初期中,我们粗略地认为L的终点方向是由第n个点和第n-1个点决定的,从而确定箭头的方向和位置。
不过,这种设计真的合理吗?让我们看看图5-7出现的问题。
出现图5-7中的情况,是因为用户当即将绘制完成曲线L时误触屏幕造成了“回钩”,导致最后一个点(B点)落到了点A之前.按照之前的解决思路,箭头的方向是(AB) ⃗,因此就会出现图中的情况,如何避免这种情况呢?
为解决上述问题,我们在确定曲线方向时由三个点A(x_(n-2),y_(n-2) ),B(x_(n-1),y_(n-1) ),C(x_n,y_n )来对曲线方向进行约束。在这里引出一个__自定义概念__叫做__终点的有效落点__:如图5-9所示,过A点做AB的垂线DF,过B点做AB垂线EG,落在__矩形区域DFGE内的点均不是C的有效落点__,否则点C就是C的有效落点,C的有效落点可以__通过BC两点判断L的最终方向。__
具体解决步骤如下:
Step1:首先由点A,B可以确定直线方程:
其中a , b, c为未知参数,确定直线位置。将点A (x_(n-2),y_(n-2) ),B (x_(n-1),y_(n-1) )带入上式确定参数a ,b ,c。
由于直线DF,GE分别与直线AB垂直,故已确定了直线L,易确定直线DF方程L_1,GE方程L_2:
Step2:已知C点坐标为(x_n,y_n ),可以分别求出点C到L_1的距离d_1,到L_2的距离d_2以及到L的距离d。设直线DF和EG长度已知为μ,AB直线长度d_l。
Step3:判断点C是否为有效落点。
若d_1+d_2>d_l或者d >μ,说明C点在矩形外面,即C点为C的有效落点。
若d_1+d_2≤d_l并且d<=μ,说明C点在矩形内,即C点不是C的有效落点。
那么,DF、EG的长度μ,取何值是较为合理的呢?若想减少用户误触屏幕对箭头方向的影响,提高箭头方向的正确性,则在DF、EG构成的平面内,CC_1、CC_2不应与AB相交。
如图5-10,由直线CC_1,CC_2构成一个箭头,其中CC_1和CC_2长度均为v,并且CC_1⊥CC_2,则取μ=2*v,即两倍的CC_1。证明如下:
C点从B点沿着BEDA路线移动时,直线CC_1与直线AB的夹角范围是45°~135°。
- 当C点在BE之间时,若CC_1与AB不相交,BC> √2/2v ,所以BE ≥ BC
- 当C点在ED之间时,若CC_1与AB不相交,则只要保证CC_1⊥AB时不想交,即BE > v。
- 当C点在DA之间时,若CC_1与AB不相交,设CC_1与AD夹角为θ,则需要保证μ>v_cosθ(0°<θ<90°)。
综上,v > v_cosθ >√2/2v ,所以取μ=2*v。
如图5-11所示,此时C为有效落点,将BC两点作为方最后两个点确定箭头方向。如图5-12所示,此时C不是有效落点,把AB两点作为最后两个点确定箭头方向。
呼,终于解决了令人头疼的箭头,这可是个让我们的前端小哥哥头痛了七天七夜的问题。
六、尾声
回望这一路,时间过的很快,长沙站的赛区决赛也已经结束多日,我们小黑板上距离微信小程序全国总决赛的倒计时也从两位数变成了个位数,大胆展出我们的小黑板。
这一路上,Attack 足球团队已经和足球结下了不解之缘。足球是一种文化,是一种艺术,更是一种精神。它蕴含着奉献、实干、进步,蕴含着团队协作、顽强拼搏、永不言败、永葆激情等精神。而这些精神,也是我们团队不断内化的地方。本次大赛提供了这么一个机会,以赛促学、以赛促教、以赛促用,使我们每个人都有了蜕变,我们也会抓住这个机会,带着足球教会我们的精神,全力以赴,将更好的Attack 足球呈现给大家。
最后放上我们的小程序二维码,为了保证鲁棒性,最新版的Attack足球还在最后的测试阶段,不过现在已上线的版本不影响基本功能的正常使用,各位可以体验一下,更欢迎有球迷朋友来和我们沟通交流!谢谢!