单例模式

单例模式有两种:“饿汉模式”和“懒汉模式”。直接使用饿汉模式,懒汉模式在任何情况下都不需要使用,因为饿汉模式先天就没有线程安全问题。

懒汉单例模式终极版

用volatile和synchronized配合双重检查锁(DCL:double check lock)机制,其中volatile用来保证多线程下的可见性:

  • 读volatile:每当子线程某一语句要用到volatile变量时,都会从主线程重新拷贝一份,这样就保证子线程的跟主线程的一致。
  • 写volatile: 每当子线程某一语句要写volatile变量时,都会在读完后同步到主线程去,这样就保证主线程的变量及时更新。

或者认为用volatile修饰singleton并不是用了volatile的可见性,而是用了java内存模型的“先行发生”(happens-before)原则的其中一条Volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作,这里的“后面”指时间上的先后顺序。这样禁止指令重排序,确保singleton对象是在初始化完成后才能被读到。

public class Singleton {
private static volatile Singleton uniqueInstance;

private Singleton(){
}

public static Singleton getInstance(){
if(uniqueInstance == null){ //#1
synchronized(Singleton.class){ //#2
if(uniqueInstance == null){ //#3
uniqueInstance = new Singleton(); //#4
System.out.println(Thread.currentThread().getName() + ": uniqueInstance is initalized..."); //#5.1
} else {
System.out.println(Thread.currentThread().getName() + ": uniqueInstance is not null now..."); //#5.2
}
}
}
return uniqueInstance;
}
}

饿汉单例模式

以下两种写法在编译后等效

public class Singleton {
    private static final Singleton singleton=new Singleton();
    
    public static Singleton getInstance(){
        return singleton;
    }
}
public class Singleton {
    private static Singleton singleton;
    
    static{
        singleton=new Singleton();
    }
    
    public static Singleton getInstance(){
        return singleton;
    }
}

类的加载分为5个步骤:加载、验证、准备、解析、初始化,“饿汉模式”的创建对象是在类加载的初始化阶段进行的,jvm规范规定有且只有以下7种情况下会进行类加载的初始化阶段:

  • 使用new关键字实例化对象的时候
  • 设置或读取一个类的静态字段(被final修饰,已在编译器把结果放入常量池的静态字段除外)的时候
  • 调用一个类的静态方法的时候
  • 使用java.lang.reflect包的方法对类进行反射调用的时候
  • 初始化一个类的子类(会首先初始化父类)
  • 当虚拟机启动的时候,初始化包含main方法的主类
  • 当使用jdk1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。

基本来说就是只有当以某种方式调用了这个类的时候,它才会进行初始化,而不是说jvm启动的时候就初始化。所以说假如单例类里只有一个getInstance()方法,那相当于当从其他类调用getInstance()方法的时候才会进行初始化,这和“懒汉模式”一样的效果。而jvm本身会确保类的初始化只执行一次。

当单例类里除了getInstance()方法还有一些其他静态方法,这样当调用其他静态方法的时候,也会提前初始化实例了。解决这个问题只要加个内部类就行了,这种模式叫holder pattern,如下,只有当调用getInstance()方法的时候,才会初始化内部类SingletonHolder:

public class Singleton {
    private static class SingletonHolder{
        private static final Singleton instance=new Singleton();
    }
    
    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
}

单元素enum来实现单例

public enum Singleton
{
    INSTANCE;

    public void dosomething()
    {
        System.out.println(this + " is speaking!");
    }
}

微服务

传统开发中的景象

程序员们日以继夜,诠释着披星戴月的含义,却不断的沉沦在重复搭建环境、重复系统部署、重复环境验证、重复代码开发等等的炼狱之中,“感觉身体被掏空”的绝望如影随形。
大型软件项目已成为大量代码的随机而无序的堆积。工程师一旦完成项目,就恐避之不及,不愿再去碰自己几个月来夜以继日的劳动成果。

微服务架构

微服务的概念源于 2014 ,服务架构是一种架构模式,需要几个基础的服务治理组件相互协作,包括服务注册与发现、服务消费、负载均衡、断路器、智能路由、配置管理等。

Restful

REST — REpresentational State Transfer 表现层状态转移,是一种架构风格,不是技术体系。
URL定位资源,用HTTP动词(GET,POST,DELETE,PUT)描述操作。
即通过HTTP动词来实现资源的状态扭转:

  • GET 获取资源
  • POST 新建资源(也可用于更新资源)
  • PUT 更新资源
  • DELETE 删除资源,有的业务系统中,删除只做逻辑删除,即只设置资源为已删除状态。

GET、PUT、DELETE操作是幂等的,安全和幂等的意义在于:当某个操作没有达到预期的目标时,我们可以不停的重试这个操作,而不会对资源产生副作用。
创建操作可以使用POST,也可以使用PUT,区别在于POST是作用在一个集合资源之上的(/uri),而PUT操作是作用在一个具体资源之上的(/uri/xxx),可以理解为,如果URL可以在客户端确定那么就使用PUT,如果是在服务端确定那么就使用POST。
现在也有的设计只用GET和POST,把具体操作写在uri中。

幂等

在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“setTrue()”函数就是一个幂等函数,无论多少次执行其结果都是一样的。

保证幂等性主要是三点:
1.对于每个请求必须有一个唯一的标识
2.每次处理完请求之后,必须有一个记录标识这个请求处理过了
3.每次接收请求需要进行判断,判断之前是否处理过

CAP理论

任何分布式系统在一致性、可用性、分区容错性三方面不能兼得,最多得其二,因此任何分布式系统的设计只是在三者中的不同取舍。
Consistency(一致性):所有节点上数据时刻同步
Availability(可用性):在一定时间能响应客户端的请求
Partition tolerance(分区容错):允许出现网络分区

分区

分区是指网络分区,分布式系统中各节点不再连通。一个分布式系统里面,节点组成的网络本来应该是连通的。然而可能因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域,数据就散布在了这些不连通的区域中。
当一个数据项只在一个节点中保存,那么分区出现后,和这个节点不连通的部分就访问不到这个数据了。这时分区就是无法容忍的。提高分区容忍性的办法就是一个数据项复制到多个节点上。
然而,把数据复制到多个节点会带来一致性的问题。要保证一致,每次写操作就都要等待全部节点写成功,而这等待又会带来可用性的问题。
总的来说就是,数据存在的节点越多,分区容忍性越高,但要复制更新的数据就越多,一致性就越难保证。为了保证一致性,更新所有节点数据所需要的时间就越长,可用性就会降低。
实际上这在分布式系统中一般认为P是必须的,所以AC需要权衡。
满足AC意味着网络分区不能发生;而当存在网络分区时,将不再同时保证AC。有一个等价的理论:在一个不可靠的分布式环境中,无法同时满足活性(A)和安全性(C)。

微服务实践

服务拆分原则:
(1)横向拆分。按照不同的业务域进行拆分,形成独立的业务领域微服务集群。
(2)纵向拆分。把一个业务功能里的不同模块或者组件进行拆分。把公共组件拆分成独立的原子服务,下沉到底层,形成相对独立的原子服务层。
做好微服务的分层:梳理和抽取核心应用、公共应用,作为独立的服务下沉到核心和公共能力层,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
微服务的拆分力度需与具体业务相结合,总的原则是服务内部高内聚,服务之间低耦合

微服务架构是一种架构模式或者架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

微服务vs传统开发:
部署方式不同,在微服务上自动化运维不可不上。

如何解决微服务架构中的身份验证问题?
http://mt.sohu.com/20161221/n476556655.shtml

模块化与微服务

正确的组织方式是:独立出来各个业务无关功能的静态模块或动态服务,方便各项目的各子系统快速集成。包括:短信发送功能,数据库模块,权限验证功能,公共方法模块等。保持模块功能单一性,使工程不引入无关的功能模块。
阿里云中也提供收费的短信发送服务。
独立服务不会出现包冲突,独立模块不用单独部署服务。微服务是加强了的模块化。
最终策略:优先使用Maven模块化组合,当模块化不能满足时,再升级模块为微服务。

模块化还是微服务 – 为什么说大部分团队微服务化都走入了陷阱
http://www.sohu.com/a/149458799_256833

当系统需要提升处理能力时,可选择重置扩展架构和水平扩展架构,

心得:
微服务架构,需要每个人完整完善的完成相关服务。
不同的语言和开发环境对编码过程中的严谨程度要求不一样。
前后端分离,要根据数据存储特点,数据传输效率定义接口。
在编码前要有充分反复的需求分析、开发设计和程序设计。
不要过度设计,利用程序自动化,减少和局部化手工工作,减少代码重复冗余。
注明采用特殊设计或特殊编码方式的原因。
不要留下设计和技术债务。

对服务四种分类

不同服务迁移的优先级不同:

  • 基础服务,是一些基础组件,与具体的业务无关。比如:短信服务、邮件服务。最容易摘出来做微服务,是第一优先级分离出来的服务。
  • 业务服务,是一些垂直的业务系统,只处理单一的业务类型,比如:风控系统、积分系统、合同系统。这类服务职责比较单一,根据业务情况来选择是否迁移,比如突然有需求对积分系统进行大优化,则趁机将积分系统进行改造,是第二优先级分离出来的服务。
  • 前置服务,前置服务一般为服务的接入或者输出服务,比如网站的前端服务、app 的服务接口,是第三优先级分离出来的服务。
  • 组合服务,组合服务是涉及到了具体的业务,比如买标过程,需要调用很多垂直的业务服务,这类的服务一般放到最后再进行微服务化架构来改造,因为这类服务最为复杂,除非涉及到大的业务逻辑变更,否则是不会轻易进行迁移。

每个微服务都有自己独立的数据库,那么后台管理的联合查询怎么处理?有如下三种处理方案:

  • 严格按照微服务的划分来做,微服务相互独立,各微服务数据库也独立,后台需要展示数据时,调用各微服务的接口来获取对应的数据,再进行数据处理后展示出来,这是标准的用法,也是最麻烦的用法。
  • 将业务相关的表放到一个库中,将业务无关的表严格按照微服务模式来拆分,这样既可以使用微服务,也避免了数据库各种切换导致后台统计难以实现,是一个折中的方案。
  • 数据库严格按照微服务的要求来切分,以满足业务高并发,实时或者准实时将各微服务数据库数据同步到 NoSQL 数据库中,在同步的过程中进行数据清洗,用来满足后台业务系统的使用,推荐使用 Mongodb、Hbase 等。

其它结构型模式

组合模式

组合模式将对象组合成树形结构,以表示部分-整体的层次结构。
它使得用户对单个对象的操作与对组合对象的操作具有一致性。
抽象组件接口中声明添加、删除和一些其它业务方法,节点组件实现所有方法,叶节点只需实现其它业务方法。
组合模式带来的操作一致性是透明方式的体现,叶节点和节点一样也含有添加删除方法,但没有意义。另一种方式是安全方式,即抽象组件接口中不声明添加、删除方法,让树叶和树枝实现不同的接口,但这样客户端调用时需要做判断,带来了操作不一致。
当需求中体现了部分与整体层次的结构时,或者希望用户可以忽略组合对象与单个对象的不同时,就应该考虑使用组合模式了。
很多界面控件的基类中都有Add、Remove方法,这就是典型的组合模式的应用。

享元模式

运用共享技术有效地支持大量细粒度的对象
Flyweight模式的核心是把大量共享的对象收集在一起,使用简单工厂模式进行管理,避免由于大量小对象导致系统内存过渡消耗

代理模式

代理模式和装饰模式有相同点,都可以很容易地在真实对象的方法前面或者后面加上自定义的方法:
对装饰器模式来说,装饰者(decorator)和被装饰者(decoratee)都实现同一个接口。
同样地,对代理模式来说,代理类(proxy class)和真实处理的类(real class)都实现同一个接口。

使用的场景不一样:
比如IO流使用的装饰者模式,可以层层增加功能。
代理模式可以用于增加特殊的功能。有些动态代理不支持多层嵌套。
两者的目的不同:

工厂模式

工厂的作用

工厂用来实例化对象,使用工厂是隐藏变化的一种自然结果。
先考虑需要什么对象,然后关注如何创建对象,即先确定对象后定义工厂。

几个与工厂有关的模式

  • 单例模式;
  • 工厂方法模式;
  • 原型模式;
  • 抽象工厂模式;
  • 建造者模式;

它们都归为创建型模式。

管理和使用原则

两种视角:使用视角、创建/管理视角
两个实体之间的关系只能有下面一种,或者为A使用B,或者为A管理B。这样降低耦合度。
分清了对象的定义工作和管理工作后,我们说能事半功倍

工厂模式分为3类:

  • 简单工厂模式(Simple Factory)
  • 工厂方法模式(Factory Method)
  • 抽象工厂模式(Abstract Factory)

简单工厂模式中,产品是抽象的,工厂不是抽象的,在工厂类中面对各种具体产品。这个工厂类不符合开闭原则。工厂类中提供不同方法生成不同的具体产品。调用者面对的是一个工厂类和它们的各个方法。

工厂方法模式定义一个用于创建对象的成员方法,让子类在这个方法中决定创建哪个对象。
工厂方法模式中,产品是抽象的,工厂也是抽象的,每个具体工厂类面对一个具体产品。调用者要面对各个具体工厂类和它们的统一方法。
工厂方法会使得工厂对象的数量增长。可以考虑使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实现。
工厂方法模式要创建的东西本身是抽象定义的,并且工厂类本身也可能是抽象的。
工厂方法模式将“使用哪些对象”的规则与“如何使用这些对象”的逻辑分离开来。

有时虽然有几组对象,但并不需要每个组都用不同的派生类控制其实例化,可以更加动态一些:使用配置文件指定使用哪些对象,用switch实例化正确的对象。

反射技术
菜鸟程序员碰到问题,只会用时间来摆平。所以即使整天加班,老板也不想给加工资。
所有在用简单工厂的地方,都可以考虑用反射技术+配置文件来去除switch或if,解除分支判断带来的耦合。

Abstract Factory模式为创建一组相关的对象提供一个接口,无需指定具体类。注意这里是创建一组对象,即接口中可能提供每种对象的创建方法。

抽象工厂模式与工厂方法模式的区别
工厂方法模式是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂方法模式的一种推广。
工厂方法模式用来创建一个产品的等级结构,而抽象工厂模式用来创建多个产品的等级结构。工厂方法创建一般只有一个方法,创建一种产品。抽象工厂一般有多个方法,创建一系列产品。
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。

switch语句说明:
这里可能需要抽象:
需要多态行为;
存在职责错放;
工厂模式并不能消除switch,它将使用switch的职责从调用者中转移了。
switch语句本身没有问题,只有在switch语句互相耦合,比如许多switch语句使用同一个变量作为开关时,这种连接点变成一种依赖性,带来复杂和bug。

示例:
在java中,iterator()方法是工厂方法。
在c++中,begin(),end()都是工厂方法。

一个工厂方法的细节扩展:模板工厂方法
在模板模式中,抽象类中的一个模板方法是用来创建抽象对象的,创建何种具体类推迟到子类中实现。 这个模板工厂方法一般是保护的。

另一个细节延伸模式:建造者模式
建造者模式是围绕构建过程展开的模式。
用于创建一些复杂的对象,这些对象内部构建间的建造过程顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
建造者继承建造接口类,必须实现所有技能;指挥者指挥建造者按顺序施展一些技能。
建造者模式可以把创建复杂对象的算法从该对象的组成部分中独立出来。

可以觉察到,模板工厂方法和建造者模式也是相似的。

再一个建造者模式:Prototype 原型模式
它就是Clone已有对象,基类中提供Clone(),Copy()方法,Clone()方法实现浅复制,Copy()方法实现深复制。

设计模式的分类

根据概念性动机分3类设计模式:

  1. 创建型模式:管理对象的创建。 常用的有单例模式,简单工厂模式,工厂方法模式,原型模式,抽象工厂模式,建造者模式。
  2. 结构型模式:将已有对象加入到的的设计中时,使用结构型模式作为指导。 常用的有外观模式,适配器模式,桥接模式,装饰模式,组合模式,享元模式,代理模式。
  3. 行为型模式:定义对象时,使用行为型模式指导。 常用的有观察者模式,策略模式,模板方法模式,命令模式,状态模式,职责链模式,解释器模式,中介者模式,访问者模式,备忘录模式,迭代器模式。

设计模式的推导

标准化结构程序设计->面向对象范型(或思想)->设计原则->设计模式

设计模式(面向对象)有七大原则:迪依接单里开
1.开放-封闭原则 2.单一职责原则 3.依赖倒转原则 4.迪米特法则(也称为最小知识原则) 5.接口隔离原则 6.里氏代换原则 7.合成/聚合复用原则

面向对象编程的三大主要特性是:封装、继续、多态。简称疯子(ji)多。

中介者模式

中介者模式的核心

  • 它贯彻了迪米特法则,通过把众多对象间的交互独立封装出来,使众多的独立对象之间松耦合。

复习迪米特法则

  • 又称最小知识原则,尽量减小两个类间的直接通信。
  • 如果它们之间需要建立调用关系,尽可能通过第三者转发调用。
  • 迪米特法则强调在类的结构设计上,每一个类都应当尽量降低成员的访问权限。
  • 它的根本思想是强调了类之间的松耦合。类之间的耦合越弱,越利于复用。弱耦合关系的类的修改涉及影响最小。

中介者模式的要点

  • 背景是将系统分割出许多对象可以增加复用性,但若对象间的连接太多则又降低了复用性;
  • 通过中介者对象,将网状的连接结构变成以中介者为中心的星形结构;
  • 中介者模式中的主要工作在交互的封装上,控制了集中化,把交互复杂性变为了中介者的复杂性,所以当系统出现多对多交互复杂的对象群时,要先考虑设计的合理性;

网络安全

请求安全

1.Token,传输token代替用户名和密码。向授权用户返回Token时,同时带上Token过期时间。
2.签名,约定签名生成算法,我在提交积分流程中做法是,客户端对一些参数的某进行加盐MD5,服务端同样对这些参数的某进行加盐MD5。在服务端判断若结果相同则鉴权成功。其中的盐由服务端根据客户端设备标识动态生成,返回给客户端。
3.随机数,服务端记录由随机数标识的请求,防止重复请求。
4.时间戳,服务端对例如大于5分钟时间差的请求直接拒绝,否则再结合随机数参数判断处理请求。

https://www.cnblogs.com/PerkinsZhu/p/9713836.html

数据加密算法

1.单向加密:MD5、SHA、HMAC,不可逆不能解密。信息摘要算法目的是用来校验文件/数据是否和原始数据一致,可以作为计算sign签名的算法。
2.(双向)对称加密:DES、AES、PBE,加密和解密使用相同的密钥。
3.(双向)非对称加密:RSA、DH,公钥和私钥互为加解密钥。
公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。加密和解密使用的是两个不同的密钥,这种算法叫作非对称加密算法。非对称加密安全性更好,缺点是加密和解密速度慢,只适合对少量数据进行加密。

编码算法

Base64、URL密码,目的是为了解决部分网络传输不支持不可见字符的问题。通过Base64编码把数据流转化为可打印显示的安全字符,之后通过网络进行传输。应用场景:RSA的公钥为byte数组,可以通过Base64编码把byte数组转换为字符串,然后传给客户端。
ProtoBuf,

HTTPS

SSL或TSL,位于应用层和传输层之间。 非对称加密算法在一些情况下会与对称加密算法一起使用,HTTPS 就是一个典型的应用场景。 简单说就是: 部分过程是一方先生成一个对称加密密钥,然后通过非对称加密的方式来发送这个密钥,这一步是确定对称密钥,之后双方的数据通信就可以用对称加密这种高效率的算法进行加解密了。

TCP三次握手四次挥手详解
https://www.cnblogs.com/zmlctt/p/3690998.html

HTTPS加密过程和TLS证书验证
https://www.jianshu.com/p/f6b34381beac

Web安全

客户端跨站点脚本攻击(XSS)和请求伪造(CSRF)。
服务端SQL注入和基于条件的SQL攻击。
服务端分布式拒绝服务(DDOS)攻击:
服务端会话固定(Session Fixation)攻击:

密码加密

HTTP 可以直接注入脚本,直接拿到用户输入的密码。但是注入脚本就是代价,只要能够提高一点点门槛就有意义。前端加密密码虽然不能防劫持,但是在若被劫持后能提高泄漏明文的难度。
方案1:前端提交Md5加密的密码。后端存储Md5二次加密的密码。

Web前端密码加密是否有意义?
https://blog.csdn.net/xl_lx/article/details/79075386

职责链模式

职责链模式的核心内容

  • 降低了请求对象和处理对象之间,及处理对象之间的耦合。

职责链模式的要点

  • 构造了一个链结构,链节点只持有下一个节点的引用,不需要知道链中的所有节点,降低了耦合度;
  • 链节点即职责对象,职责类继承自共同的基类,有共同的抽象行为,由于职责权限不同而实现了不同的派生类;
  • 请求者只需要调用第一个职责对象,余下的事全交给它了;
  • 从而请求事件由第一个职责对象自动沿链逐个传递处理;
  • 请求对象在被处理过程中可能被转移处理,或被附加处理

dubbo

Dubbo 是 SOA 服务治理的一种方案,同时也是高性能的 RPC 调用框架。

ZooKeeper

ZooKeeper是分布式锁的实现者。
目前在分布式协调技术方面做得比较好的就是Google-Chubby和Apache-ZooKeeper,他们都是分布式锁的实现者。Chubby是非开源Google自家用。雅虎模仿Chubby开发出了ZooKeeper,也实现了类似的分布式锁的功能,并且将ZK作为一种开源的程序捐献给了Apache。

ZooKeeper是一种为分布式应用所设计的高可用、高性能且一致的开源协调服务,它提供了一项基本服务:分布式锁服务。开发者在分布式锁的基础上,摸索了出了其他的使用方法:配置维护、组服务、分布式消息队列、分布式通知/协调、域名服务等。

ZooKeeper设计一种新的数据结构——Znode,然后在该数据结构的基础上定义了一些原语,也就是一些关于该数据结构的一些操作。有了这些数据结构和原语后,因为在一个分布式的环境下服务是通过消息以网络的形式发送给我们的分布式应用程序,所以还需要一个通知机制——Watcher机制。那么ZooKeeper所提供的服务主要是通过:数据结构Znode+原语+watcher机制,三个部分来实现的。

Zookeeper是一个分布式的服务框架,是树型的目录服务的数据存储,能做到集群管理数据,这里能很好的作为Dubbo服务的注册中心。Dubbo能与Zookeeper做到集群部署,当提供者出现断电等异常停机时,Zookeeper注册中心能自动删除提供者信息。当提供者重启时,能自动恢复注册数据,以及订阅请求。

https://www.cnblogs.com/wuxl360/p/5817471.html

其它

处理密码重置和电子邮件确认等特权操作,要使用一次性随机令牌。

译见|构建用户管理微服务(一):定义领域模型和 REST API

安全设计技术栈(非功能性需求):
1.当用户登录时,将为他们生成一个 JWT 令牌,有效期是 24 小时。在后续请求中包含此令牌,用户可以执行需要身份验证的操作
2.密码重置令牌有效期为 10 分钟,电子邮件地址确认令牌为一天
3.密码用加密算法(Bcrypt)加密,并且每用户加盐

在领域驱动设计DDD中,先设计领域模型。

值对象
当设计领域模型,值对象提供了一种方便的方式来描述携带有一定的信息片段属性的集合。 AddressData,AuditData,ContactData 和 Password 因此可以认为是值对象。

Tars

在Spring Cloud中使用Tars
github地址:https://github.com/Tencent/Tars
http://springcloud.cn/view/247