创建一个空的父工程

创建SpringBootAdminServer子模块

在启动类添加@EnableAdminServer注解,开启Admin监控

@SpringBootApplication
@EnableAdminServer
public class AdminServerApplication {public static void main(String[] args) {SpringApplication.run(AdminServerApplication.class, args);}
}

配置application.yml

spring:#  应用名称application:name: admin-server
server:port: 8888

运行项目

创建SpringBootAdminClient子模块

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>xyz.sunjing</groupId><artifactId>admin-client</artifactId><version>0.0.1-SNAPSHOT</version><name>admin-client</name><description>This is a Spring Boot Admin Demo Project</description><properties><java.version>1.8</java.version><spring-boot-admin.version>2.3.0</spring-boot-admin.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-dependencies</artifactId><version>${spring-boot-admin.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

配置application.yml

spring:application:name: admin-clientboot:admin:client:# Spring Boot Admin Server地址url: http://localhost:8888management:endpoints:web:exposure:include: '*'endpoint:health:show-details: always

运行项目

集成SpringSecurity

Server模块

Server模块引入依赖

     <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>

在application.yml中配置用户名和密码

spring:application:name: admin-serversecurity:user:name: rootpassword: root
server:port: 8888

在启动类中编写Security配置类

@SpringBootApplication
@EnableAdminServer
public class AdminServerApplication {public static void main(String[] args) {SpringApplication.run(AdminServerApplication.class, args);}@Configurationpublic static class AdminServerSecurityConfig extends WebSecurityConfigurerAdapter {private final String adminContextPath;public AdminServerSecurityConfig (AdminServerProperties adminServerProperties) {this.adminContextPath = adminServerProperties.getContextPath();}@Overrideprotected void configure(HttpSecurity http) throws Exception {// @formatter:offSavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();successHandler.setTargetUrlParameter("redirectTo");successHandler.setDefaultTargetUrl(adminContextPath + "/");http.authorizeRequests().antMatchers(adminContextPath + "/assets/**").permitAll()//Grants public access to all static assets and the login page..antMatchers(adminContextPath + "/login").permitAll().anyRequest().authenticated()//   Every other request must be authenticated..and().formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()//Configures login and logout..logout().logoutUrl(adminContextPath + "/logout").and().httpBasic().and()//Enables HTTP-Basic support. This is needed for the Spring Boot Admin Client to register..csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())// Enables CSRF-Protection using Cookies.ignoringAntMatchers(adminContextPath + "/instances",// Disables CRSF-Protection the endpoint the Spring Boot Admin Client uses to register.adminContextPath + "/actuator/**"//Disables CRSF-Protection for the actuator endpoints.);}}}

Client模块的application.yml中配置用户名和密码

spring:application:name: admin-clientboot:admin:client:# Spring Boot Admin Server地址url: http://localhost:8888# 在这里加入server模块中配置的用户名和密码username: rootpassword: rootmanagement:endpoints:web:exposure:include: '*'endpoint:health:show-details: always

运行两个项目


Client模块

引入依赖

     <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>

配置application.yml

spring:application:name: admin-clientboot:admin:client:# Spring Boot Admin Server地址url: http://localhost:8888# 在这里加入server模块中配置的用户名和密码username: rootpassword: root# 配置该信息以授权服务端以HTTP BASIC方式访问端点instance:metadata:user.name: ${spring.security.user.name}user.password: ${spring.security.user.password}# 配置用户名密码security:user:name: clientpassword: clientmanagement:endpoints:web:exposure:include: '*'endpoint:health:show-details: always
debug: true

运行项目

集成邮箱报警功能

在server模块中引入依赖

     <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>

在application.yml中配置

spring:application:name: admin-serversecurity:user:name: rootpassword: rootmail:host: smtp.163.comusername: 邮箱账号password: 授权码properties:mail:smtp:auth: truestarttls:enable: truerequired: trueboot:admin:#  开启邮箱通知notify:mail:#  收件方to: to@example.com#  发件方from: from@example.com
server:port: 8888

配置邮箱发送模板

在服务端resources->templates文件夹下创建status-changed.html文件

<!DOCTYPE html>
<!--~ Copyright 2014-2018 the original author or authors.~~ Licensed under the Apache License, Version 2.0 (the "License");~ you may not use this file except in compliance with the License.~ You may obtain a copy of the License at~~     http://www.apache.org/licenses/LICENSE-2.0~~ Unless required by applicable law or agreed to in writing, software~ distributed under the License is distributed on an "AS IS" BASIS,~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.~ See the License for the specific language governing permissions and~ limitations under the License.--><html xmlns:th="http://www.thymeleaf.org" lang="zh">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><style>h1, h2, h3, h4, h5, h6 {font-weight: 400}ul {list-style: none}html {box-sizing: border-box}*, :after, :before {box-sizing: inherit}table {border-collapse: collapse;border-spacing: 0}td, th {text-align: left}body, button {font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica, Arial, sans-serif}code, pre {-moz-osx-font-smoothing: auto;-webkit-font-smoothing: auto;font-family: monospace}</style>
</head>
<body>
<th:block th:remove="all"><!-- This block will not appear in the body and is used for the subject --><th:block th:remove="tag" th:fragment="subject">[[${instance.registration.name}]] ([[(${instance.id})]]) 当前状态 [[${event.statusInfo.status}]]</th:block>
</th:block>
<h1><span th:text="${instance.registration.name}"/> (<span th:text="${instance.id}"/>)is <span th:text="${event.statusInfo.status}"/>
</h1>
<p>实例 <a th:if="${baseUrl}" th:href="@{${baseUrl + '/#/instances/' + instance.id + '/'}}"><spanth:text="${instance.id}"/></a><span th:unless="${baseUrl}" th:text="${instance.id}"/>状态从 <span th:text="${lastStatus}"/> 变为 <span th:text="${event.statusInfo.status}"/>
</p><h2>状态详情</h2>
<dl th:fragment="statusDetails" th:with="details = ${details ?: event.statusInfo.details}"><th:block th:each="detail : ${details}"><dt th:text="${detail.key}"/><dd th:unless="${detail.value instanceof T(java.util.Map)}" th:text="${detail.value}"/><dd th:if="${detail.value instanceof T(java.util.Map)}"><dl th:replace="${#execInfo.templateName} :: statusDetails (details = ${detail.value})"/></dd></th:block>
</dl><h2>相关链接</h2>
<table><tr th:if="${instance.registration.serviceUrl}"><td>服务地址</td><td><a th:href="${instance.registration.serviceUrl}" th:text="${instance.registration.serviceUrl}"></a></td></tr><tr><td>健康检查</td><td><a th:href="${instance.registration.healthUrl}" th:text="${instance.registration.healthUrl}"></a></td></tr><tr th:if="${instance.registration.managementUrl}"><td>服务管理地址</td><td><a th:href="${instance.registration.managementUrl}" th:text="${instance.registration.managementUrl}"></a></td></tr>
</table>
</body>
</html>
在application.yml中配置模板路径
spring:#  应用名称application:name: admin-server# 安全配置security:user:name: adminpassword: zdGt5UKrrZ# 邮箱配置mail:host: smtp.163.comusername: 17629108513@163.compassword: FWFZTPHETTXVBNQWproperties:mail:smtp:auth: truestarttls:enable: truerequired: trueboot:admin:#  开启邮箱通知notify:mail:#  收件方to: sunjingxa@foxmail.com#  发件方from: 17629108513@163.com#  配置发送邮件模板template: classpath:/templates/status-changed.htmlserver:#  修改端口port: 8888

配置在线查看日志

在client模块中加入logback配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false"><include resource="org/springframework/boot/logging/logback/defaults.xml"/><!-- 应用名称--><property name="appName" value="online-exam"/><!-- 日志的存放目录--><!-- debug--><property name="SBA_LOG_FILE_NAME_PATTERN" value="/opt/logs"/><property name="DEBUG_LOG_FILE_NAME_PATTERN" value="/opt/logs/${appName}-debug.%d{yyyy-MM-dd}.%i.log"/><property name="INFO_LOG_FILE_NAME_PATTERN" value="/opt/logs/${appName}-info.%d{yyyy-MM-dd}.%i.log"/><property name="WARN_LOG_FILE_NAME_PATTERN" value="/opt/errLogs/${appName}-warn.%d{yyyy-MM-dd}.%i.log"/><property name="ERROR_LOG_FILE_NAME_PATTERN" value="/opt/errLogs/${appName}-error.%d{yyyy-MM-dd}.%i.log"/><!-- 日志格式 --><property name="CONSOLE_LOG_PATTERN"value="%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%c){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/><property name="FILE_LOG_PATTERN"value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %c : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/><!--输出到控制台--><appender name="console" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern></encoder></appender><!--输出SBA日志--><appender name="sba_file" class="ch.qos.logback.core.rolling.RollingFileAppender"><encoder><pattern>${FILE_LOG_PATTERN}</pattern></encoder><file>${SBA_LOG_FILE_NAME_PATTERN}/sba-server.log</file><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_PATH}/demo-server-%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>30MB</maxFileSize><maxHistory>30</maxHistory></rollingPolicy></appender><!--输出到DEBUG文件--><appender name="debug_file" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${DEBUG_LOG_FILE_NAME_PATTERN}</fileNamePattern><!-- 日志保留天数 --><maxHistory>30</maxHistory><!-- 日志文件上限大小,达到指定大小后删除旧的日志文件 --><totalSizeCap>1GB</totalSizeCap><!-- 每个日志文件的最大值 --><timeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>50MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><encoder><pattern>${FILE_LOG_PATTERN}</pattern></encoder><!-- 此日志文件只记录debug级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>debug</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!--输出到INFO文件--><appender name="info_file" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${INFO_LOG_FILE_NAME_PATTERN}</fileNamePattern><!-- 日志保留天数 --><maxHistory>7</maxHistory><!-- 日志文件上限大小,达到指定大小后删除旧的日志文件 --><totalSizeCap>1GB</totalSizeCap><!-- 每个日志文件的最大值 --><timeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>50MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><encoder><pattern>${FILE_LOG_PATTERN}</pattern></encoder><!-- 此日志文件只记录info级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>info</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!--输出到WARN文件--><appender name="warn_file" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${WARN_LOG_FILE_NAME_PATTERN}</fileNamePattern><!-- 日志保留天数 --><maxHistory>30</maxHistory><!-- 日志文件上限大小,达到指定大小后删除旧的日志文件 --><totalSizeCap>1GB</totalSizeCap><!-- 每个日志文件的最大值 --><timeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>10MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><encoder><pattern>${FILE_LOG_PATTERN}</pattern></encoder><!-- 此日志文件只记录warn级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>warn</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!--输出到ERROR文件--><appender name="error_file" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${ERROR_LOG_FILE_NAME_PATTERN}</fileNamePattern><!-- 日志保留天数 --><maxHistory>30</maxHistory><!-- 日志文件上限大小,达到指定大小后删除旧的日志文件 --><totalSizeCap>1GB</totalSizeCap><!-- 每个日志文件的最大值 --><timeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>10MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><encoder><pattern>${FILE_LOG_PATTERN}</pattern></encoder><!-- 此日志文件只记录error级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>error</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- region 根据不同的环境设置不同的日志输出级别 --><springProfile name="dev"><root level="info"><appender-ref ref="console"/><appender-ref ref="sba_file"/></root></springProfile><springProfile name="prod,test"><root level="info"><appender-ref ref="console"/><appender-ref ref="sba_file"/><appender-ref ref="debug_file"/><appender-ref ref="info_file"/><appender-ref ref="warn_file"/><appender-ref ref="error_file"/></root></springProfile><!-- endregion --></configuration>

重点关注

 <!-- 日志的存放目录--><property name="SBA_LOG_FILE_NAME_PATTERN" value="/opt/logs"/><!--输出SBA日志--><appender name="sba_file" class="ch.qos.logback.core.rolling.RollingFileAppender"><encoder><pattern>${FILE_LOG_PATTERN}</pattern></encoder><file>${SBA_LOG_FILE_NAME_PATTERN}/sba-server.log</file><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>${LOG_PATH}/demo-server-%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>30MB</maxFileSize><maxHistory>30</maxHistory></rollingPolicy></appender><springProfile name="dev"><root level="info"><appender-ref ref="console"/><appender-ref ref="sba_file"/></root></springProfile><springProfile name="prod,test"><root level="info"><appender-ref ref="console"/><appender-ref ref="sba_file"/><appender-ref ref="debug_file"/><appender-ref ref="info_file"/><appender-ref ref="warn_file"/><appender-ref ref="error_file"/></root></springProfile>

在client中配置

spring:profiles:active: devapplication:name: admin-clientboot:admin:client:# Spring Boot Admin Server地址url: http://localhost:8888# 在这里加入server模块中配置的用户名和密码username: rootpassword: root# 配置该信息以授权服务端以HTTP BASIC方式访问端点instance:metadata:user.name: ${spring.security.user.name}user.password: ${spring.security.user.password}# 配置用户名密码security:user:name: clientpassword: clientmanagement:endpoints:web:exposure:include: '*'endpoint:health:show-details: always# 开启在线日志查看功能logfile:enabled: truelogging:# 配置日志文件路径file:name: /opt/logs/sba-server.logpattern:file: '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx'

运行项目

配置在线动态修改日志级别

两种情况

客户端没有集成Spring Security

这种情况可以正常在线修改日志级别,无需其他配置

客户端集成了Spring Security

这种情况在之前配置的基础上还需要在客户端的启动类中添加一个Security的配置类,使SBA Server服务端能够访问SBA Client客户端的Actuator端点

package xyz.sunjing.adminclient;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;/*** @author sunjing*/
@SpringBootApplication
public class AdminClientApplication {public static void main(String[] args) {SpringApplication.run(AdminClientApplication.class, args);}// 添加以下配置类@Configurationpublic static class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.httpBasic().and().authorizeRequests().antMatchers("/actuator/**").authenticated().anyRequest().permitAll().and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).ignoringAntMatchers("/actuator/**");}}
}

源码地址

Spring Boot Admin 2.3 简洁Demo相关推荐

  1. Spring Boot Admin 基于security 认证监控

    首先介绍一下Spring Boot Admin是用来干嘛的,它用于监控基于 Spring Boot 的应用,它是在 Spring Boot Actuator 的基础上提供简洁的可视化 WEB UI. ...

  2. SpringCloud(8)微服务监控Spring Boot Admin

    1.简介 Spring Boot Admin 是一个管理和监控Spring Boot 应用程序的开源软件.Spring Boot Admin 分为 Server 端和 Client 端,Spring ...

  3. Spring Boot Admin 2.0 上手

    Spring Boot Admin 在 Spring Boot Actuator 的基础上提供简洁的可视化 WEB UI,是用来管理 Spring Boot 应用程序的一个简单的界面,提供如下功能: ...

  4. Spring Boot Actuator与Spring Boot Admin详解

    原版文档: 文档:Spring Boot Actuator.note 链接:http://note.youdao.com/noteshare?id=fca965ad3f7ae3f79260d09056 ...

  5. Spring Boot Admin在线查看spring boot后台日志

    当前,应用系统微服务架构.前后端分离(前端vue,后端springboot),已经成为大部分项目的标准技术架构,但在项目上线后,spring boot后端服务部署在服务器上,大部分公司对服务器都有安全 ...

  6. 用Spring Boot Admin来监控我们的微服务

    [转载请注明出处]:https://blog.csdn.net/huahao1989/article/details/108039738 1.概述 Spring Boot Admin是一个Web应用程 ...

  7. Spring Boot Admin(SBA)

    Spring Boot Admin(SBA)是一个针对Spring Boot的Actuator接口进行UI美化封装的监控工具.他可以返回在列表中浏览所有被监控Spring Boot项目的基本信息比如: ...

  8. Spring boot admin 监控配置

    1.项目背景 项目开发完成并部署上线,系统正式进入试运行:在试运行期间由于客户服务问题导致部分服务不可用,幸亏系统采用集群架构没有造成系统正常使用,但该问题存在系统风险,问题出现后没被第一时间发现和处 ...

  9. Spring Boot Admin 2.1.0 全攻略

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! Spring Boot Admin是一个开源社区项目,用于管理和监控SpringBoot应用程序. ...

最新文章

  1. python拷贝文件函数_Python Set集合,函数,深入拷贝,浅入拷贝,文件处理
  2. 网络层:IP 协议(用于封装 IP)
  3. eclipse 不能切换输入法
  4. geteditor p 取消自动_2020百度网盘超级会员怎么取消自动续费?
  5. java 上调下移_java – 在调整框架大小时,JLabel的位置会更...
  6. 阿里旺旺在线图标,在线状态生成
  7. RadASM 颜色配置
  8. arduino教程汇总
  9. 发布infopath模板到sharepoint站点(Infopath 2007)
  10. 【Python】对英文文本进行词频统计(分词、字典排序、文件读写)
  11. php实现短信找回密码,thinkphp5怎么调用云片接口实现发送短信验证码找回密码功能...
  12. 沧小海笔记本之xilinx srio核的学习记录之目录
  13. 攻防演练 第三方供应商梳理
  14. anthony1314的数论小基础
  15. 网管软件在保险行业的应用
  16. 【奇思妙想】0.1元成本柿饼派实现红外控制空调了
  17. 软件测试关于确认与验证 正确的是,验证和确认到底是什么?
  18. easypoi教程_easypoi 读取 Excel 简单应用
  19. h1283 linux内核,复苏老客 » 发布H1283双核固件0510版
  20. ubuntu下ecm驱动_Linux 下使用USB 网络

热门文章

  1. 机房收费系统的退卡和结账
  2. 逻辑思维语音01——麦当劳
  3. VUE路由防卫功能举例
  4. doodoo.js快速入门教程 1
  5. 【暖手练习】MATLAB习题
  6. 怎么快速学会计算机程序知识,零基础学电脑怎样才能学得快,自学电脑的基础知识分享...
  7. ios 判断iPhone、iPad硬件型号
  8. ECharts 饼图切换数据源bug 开始没数据显示 切换或刷新后显示
  9. [http]http转义和加解密方法
  10. 使用八种牛云存储解决方案ios7.1的app部署问题