SripingBoot 启程

Posted zhongjianYuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SripingBoot 启程相关的知识,希望对你有一定的参考价值。

微服务论文(软实力)

微服务(Microservices)——Martin Flower - 船长&CAP - 博客园 (cnblogs.com)

SpringBoot官方学习文档:https://spring.io/projects/spring-boot

1、Spring

Spring是一个开源框架,2003 年兴起的一个轻量级的Java 开发框架,作者:Rod Johnson 。

Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。

1.1、Spring如何简化Java开发

为了降低Java开发的复杂性,Spring采用了以下4种关键策略:

  • 基于POJO的轻量级和最小侵入性编程,所有东西都是bean;

  • 通过IOC,依赖注入(DI)和面向接口实现松耦合;

  • 基于切面(AOP)和惯例进行声明式编程;

  • 通过切面和模版减少样式代码,RedisTemplate,xxxTemplate;

1.2、什么是SpringBoot

就是一个javaweb的开发框架,和SpringMVC类似,对比其他javaweb框架的好处,官方说是简化开发,约定大于配置, you can “just run”,能迅速的开发web应用,几行代码开发一个http接口。


Spring Boot 基于 Spring 开发,Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用。

简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架 。

1.3、Spring Boot主要优点:

  • 为所有Spring开发者更快的入门
  • 开箱即用,提供各种默认配置来简化项目配置
  • 内嵌式容器简化Web项目
  • 没有冗余代码生成和XML配置的要求

2、微服务

2.1、什么是微服务

微服务是一种架构风格,它要求我们在开发一个应用的时候,这个应用必须构建成一系列小服务的组合;可以通过http的方式进行互通,要说微服务架构,先得说说过去的单体应用架构。

2.2、单体应用架构

所谓单体应用架构(all in one)是指,我们将一个应用中的所有应用服务都封装在一个应用中。

无论是ERP、CRM或是其他什么系统,你都把数据库访问,web访问,等等各个功能放在一个war包内。

  • 这么做的好处是,易于开发和测试;也十分方便部署;当需要扩展时,只需把war复制多份,然后放到多个服务器上,再做个负载均衡就可以了。
  • 单体应用架构缺点是,哪怕我要修改一个非常小的地方,我都需要停掉整个服务,重新打包、部署这个应用war包。特别是对于一个大型应用,我们不可能把所有内容都放在一个应用里,我们如何维护、如何分工合作都是问题。

2.3、微服务架构

all in one 的架构方式,我们把所有的功能单元放在一个应用里面。然后我们把整个应用部署到服务器上。如果负载能力不行,我们将整个应用进行水平复制,进行扩展,然后在负载均衡。

所谓微服务架构,就是打破之前all in one的架构方式,把每个功能元素独立出来。把独立出来的功能元素的动态组合,需要的功能元素才去拿来组合,需要多一些时可以整合多个功能元素。所以微服务架构是对功能元素进行复制,而没有对整个应用进行复制。

这样做的好处 :

  • 节省了调用资源
  • 每个功能元素的服务都是一个可替换的、可独立升级的软件代码。

2.4、如何构建微服务架构

一个大型系统的微服务架构,就像一个复杂交织的神经网络,每一个神经元就是一个功能元素,它们各自完成自己的功能,然后通过http相互请求调用。比如一个电商系统,查缓存、连数据库、浏览页面、结账、支付等服务都是一个个独立的功能服务,都被微化了,它们作为一个个微服务共同构建了一个庞大的系统。如果修改其中的一个功能,只需要更新升级其中一个功能服务单元即可。
​ 但是这种庞大的系统架构给部署和运维带来很大的难度。于是,spring为我们带来了构建大型分布式微服务的全套、全程产品:

  • 构建一个个功能独立的微服务应用单元,可以使用springboot,可以帮我们快速构建一个应用
  • 大型分布式网络服务的调用,这部分由spring cloud来完成,实现分布式
  • 在分布式中间,进行流式数据计算、批处理,我们有spring cloud data flow。
  • spring为我们想清楚了整个从开始构建应用到大型分布式应用全流程方案。

TF启程

我第一次开始接触到TensorFlow大概是去年五月份,大三下,如果一年多已过,我却还在写启程。。这进度,实在汗颜。。

一个完整的tensorflow程序可以分为以下几部分:

  • Inputs and Placeholders
  • Build the Graph
    • Inference
    • Loss
  • Training
  • Train the Model
  • Visualize the Status
  • Save a Checkpoint
  • Evaluate the Model
  • Build the Eval Graph
  • Eval Output

Inputs and Placeholders

对于一个完整的网络来说,必定有输入还有输出,而Placeholders就是针对网络输入来的,相当于预先给输入变量占个坑,拿mnist来说,占坑代码可以如下面的例子:

1 images_placeholder = tf.placeholder(tf.float32, shape=(batch_size,mnist.IMAGE_PIXELS))
3 labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size))

上述代码相当于为mnist图片和标签分别占坑,而tf.placeholder参数可以如下面所示:

tf.placeholder(dtype, shape=None, name=None)

即需要提供占坑数据类型dtype,占坑数据shape,当然也可以给它提供一个唯一的name

Build the Graph

因为tf是通过构建图模型来进行网络搭建的,因此搭建网络也就是’Build the Graph’。

Inference

首先就是构建图,利用一系列符号将要表达的操作表达清楚,以用于后续模型的训练。如下面代码:

1 with tf.name_scope(hidden1):
2     weights = tf.Variable(tf.truncated_normal([IMAGE_PIXELS, hidden1_units],3         stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))),name=weights)
4 
5     biases = tf.Variable(tf.zeros([hidden1_units]),6     name=biases)

如上述代码,对于一个图的搭建,需要一些变量来支持我们的运算,比如矩阵相乘等,需要通过tf.Variable来声明变量,其参数格式如下:

1 tf.Variable(self, initial_value=None, trainable=True, collections=None, validate_shape=True,2     caching_device=None, name=None, variable_def=None, dtype=None)

需要提供变量初始值initial_value, 是否接受训练trainable,对于validate_shape表示该变量是否可以改变,如果形状可以改变,那么应该为False。对于每个变量,可以赋予不同的名字tf.name_scope

Loss

在定义完图结构之后,我们需要有个目标函数,用作更新图结构中的各个变量。

1 labels = tf.to_int64(labels)
3 cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels, name=xentropy)

如上,通过给定的labels占坑变量,完成手写数字识别的最后交叉熵函数。

Training

在得到目标函数之后,我们就可以对模型进行训练,这里常用梯度下降法。在训练阶段,我们可以通过tf.scalar_summary来实现变量的记录,用作后续的tensorboard的可视化,如:

1 tf.scalar_summary(loss.op.name, loss)

然后通过tf.SummaryWriter()来得到对应的提交值。

而对于模型的最优化,这里 tf 提供了很多optimazer,通常在tf.train里面,这里常用的是GradientDenscentOptimizer(lr),然后通过调用:

1 train_op = optimizer.minimize(loss, global_step=global_step)

Train the Model

在模型训练时,我们需要打开一个默认的图环境,用作训练,如:

1 with tf.Graph().as_default():

以此来打开一个图结构,然后我们需要声明一个会话在所有操作都定义完毕之后,这样我们就可以利用这个session来运行Graph.可以通过如下方法声明:

1 with tf.Session() as sess:
2     init = tf.initialize_all_variables()
3     sess.run(init)

每次我们可以通过sess.run来运行一些操作,进而获取其输出值,

1 sess.run(fetches, feed_dict=None, options=None, run_metadata=None)

可以看到,run需要fetches,即操作,feed_dictfetches的输入,即占坑变量与其对应值构成的字典。

Visualize the Status

当然,在运行过程,我们可以通过可视化的操作来看网络运行情况。
在之前的tf.scalar_summary, 我们可以通过:

1 summary = tf.merge_all_summaries()

将在图构建阶段的变量收集起来,然后在session创建之后运行如下命令生成可视化的值。

1 summary_str = sess.run(summary, feed_dict=feed_dict)
2 summary_writer.add_summary(summary_str, step)

其中summary_writer由如下得到:

1 summary_writer = tf.train.SummaryWriter(FLAGS.train_dir, sess.graph)

然后用tensorboard打开对应文件即可。

Save a Chenckpoint

对于模型的保存,可以通过如下代码实现:

1 saver = tf.train.Saver()  
2 saver.save(sess, FLAGS.train_dir, global_step=step)

而载入模型可以通过如下的代码来实现:

saver.restore(sess, FLAGS.train_dir)

当然了,模型的估计就类似上述了。

这样简单的模型搭建到运行就完成了。本文主要用到这些函数:

    • tf.placeholder
    • tf.Variable
    • tf.train
      • tf.train.GradientDenscentOptimizer
      • tf.train.SummaryWriter
      • tf.train.Saver
    • tf.session
    • tf.Graph
    • tf.add_summary
    • tf.merge_all_summaries

其实构建一个模型基本就用这些函数,然后就是一些数理计算方法。详情参看tensorflow

以上是关于SripingBoot 启程的主要内容,如果未能解决你的问题,请参考以下文章

[硫化铂]启程的日子

Kotlin Primer·启程

AngularJS 启程

1.java并发-启程

Linux下segfault上的自重启程序

python启程——第一篇