一览无遗

  • 初识Spring Cloud 之 五大神兽
    • 一、简介
    • 二、我所了解的五大神兽
    • 三、我所理解的五大神兽
      • ①、Spring Cloud Eureka(注册中心)
        • 原理图解
        • 代码步骤
        • 代码实现
      • ②、Spring Cloud Ribbon(客户端负载均衡)
        • 什么是Ribbon?
        • 代码步骤
        • 代码实现
      • ③、Spring Cloud Hystrix(熔断器)
        • 雪崩机制详解
        • 熔断器状态机有3个状态:
        • 熔断器的核心:线程隔离和服务降级。
        • 代码实现
      • ④、Spring Cloud Feign (伪装)
        • 概念
        • 特性
        • 代码实现
      • ⑤、Spring Cloud Gateway(网关)
        • 概念
        • 核心
    • 四、Spring Cloud 小结

初识Spring Cloud 之 五大神兽

一、简介

Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发。
如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。

二、我所了解的五大神兽

 - 服务发现——Netflix Eureka- 客服端负载均衡——Netflix Ribbon- 断路器——Netflix Hystrix- 服务网关——Netflix Zuul- 分布式配置——Spring Cloud Config

三、我所理解的五大神兽

①、Spring Cloud Eureka(注册中心)

 1. Eureka:就是服务注册中心(可以是一个集群),对外暴露自己的地址2. 服务提供者:启动后向Eureka注册自己的信息(地址,提供什么服务)3. 服务消费者:向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新4. 心跳(续约):提供者定期通过http方式向Eureka刷新自己的状态

原理图解

代码步骤

 - 第一步、创建注册服务工程- 第二步、创建服务提供者--注册服务- 第三步、创建服务消费者--发现服务

代码实现

第一步、创建注册服务工程

  1. 创建maven工程,引入jar包
<!--父工程-->
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version>
</parent><!--SpringCloud包依赖管理-->
<dependencyManagement><dependencies><!--spring cloud Hoxton.SR1--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Hoxton.SR1</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>//以上代码,都可以放在父工程里面,这样就不需要在每个微服务端里都加上了<!--依赖包--><dependencies><!--eureka-server依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies>
  1. 创建 application.yml 文件
server:port: 7001    #端口号
spring:application:name: eureka-server # 应用名称,会在Eureka中作为服务的id标识(serviceId)
eureka:client:register-with-eureka: false   #是否将自己注册到Eureka中fetch-registry: false   #是否从eureka中获取服务信息service-url:defaultZone: http://localhost:7001/eureka # EurekaServer的地址
  1. 启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class,args);}
}

启动成功后,直接访问:http://localhost:7001/

第二步、创建服务提供者–注册服务

  1. 创建maven工程,引入jar包
<dependencies><!--eureka客户端--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--JPA包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!--web起步包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--MySQL驱动包--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency></dependencies>//这里是基于父工程已经创建的状态,所以父工程依赖包并没有导入。
  1. 创建 application.yml 文件
server:port: 18081
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driver
//这里有个小问题,高版本的 MySQL驱动会有时区问题,百度解决username: rootpassword: rooturl: jdbc:mysql://127.0.0.1:3306/springcloud?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTCapplication:name: user-provider #服务的名字,不同的应用,名字不同,如果是集群,名字需要相同
#指定eureka服务地址
eureka:client:service-url:# EurekaServer的地址defaultZone: http://localhost:7001/eureka
  1. 启动类
@SpringBootApplication
@EnableDiscoveryClient
public class UserProviderApplication {public static void main(String[] args) {SpringApplication.run(UserProviderApplication.class,args);}
}@EnableEurekaClient 和 @EnableDiscoveryClient 两者都可以,只是前者只适用于 Eureka 注册中心

第三步、创建服务消费者–发现服务

  1. 创建maven工程,引入jar包
<dependencies><!--eureka客户端--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--web起步依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
  1. 创建 application.yml 文件
server:port: 18082
spring:application:name: user-consumer   #服务名字
#指定eureka服务地址
eureka:client:service-url:# EurekaServer的地址defaultZone: http://localhost:7001/eureka
  1. 启动类
@SpringBootApplication
@EnableDiscoveryClient
public class UserConsumerApplication {public static void main(String[] args) {SpringApplication.run(UserConsumerApplication.class,args);}
}

到此,就完成了Eureka 注册中心的配置,以及将 服务提供者 和 服务消费者 部署到 Eureka Server 上。

②、Spring Cloud Ribbon(客户端负载均衡)

Spring Cloud Ribbon是一个基于Http和TCP的客户端负载均衡工具 ,
Ribbon主要 解决集群服务中,多个服务高效率访问的问题。
负载均衡在系统架构中是一个非常重要,并且是不得不去实施的内容。
因为负载均衡是对系统的高可用、网络压力的缓解和处理能力扩容的重要手段之一。

什么是Ribbon?

Ribbon是Netflix发布的负载均衡器,有助于控制HTTP客户端行为。为Ribbon配置服务提供者地址列表后,Ribbon就可基于负载均衡算法,自动帮助服务消费者请求。

Ribbon默认提供的负载均衡算法:轮询(默认),随机,重试法,加权。当然,我们可用自己定义负载均衡算法

Ribbon负载均衡的流程图:

代码步骤

 - 第一步、创建注册服务工程- 第二步、创建服务提供者--注册服务1- 第三步、创建服务提供者--注册服务2- 第四步、创建服务消费者--发现服务

代码实现

搭建父工程

<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version>
</properties><!--父工程-->
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version>
</parent><!--SpringCloud包依赖管理-->
<dependencyManagement><dependencies><!--spring cloud Hoxton.SR1--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Hoxton.SR1</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>

第一步、创建注册服务工程

  1. 创建maven工程,引入jar包
<!--依赖包-->
<dependencies><!--eureka-server依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>
</dependencies>
  1. 创建 application.yml 文件
server:port: 7001    #端口号
spring:application:name: eureka-server # 应用名称,会在Eureka中作为服务的id标识(serviceId
eureka:client:register-with-eureka: false   #是否将自己注册到Eureka中fetch-registry: false   #是否从eureka中获取服务信息service-url:defaultZone: http://localhost:7001/eureka # EurekaServer的地址
  1. 启动类
/*** @EnableEurekaServer 注释的类,为开启Eureka服务*/
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class,args);}
}

第二步、创建服务提供者–注册服务1

  1. 创建maven工程,引入jar包
<!--依赖包-->
<dependencies><!--JPA包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!--web起步包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--MySQL驱动包--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--eureka-client依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency></dependencies>
  1. 创建 application.yml 文件
server:port: 18081
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: rooturl: jdbc:mysql://127.0.0.1:3306/springcloud?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTCapplication:name: user-provider #服务的名字,不同的应用,名字不同,如果是集群,名字需要相同#指定eureka服务地址
eureka:client:service-url:# EurekaServer的地址defaultZone: http://localhost:7001/eureka
  1. 启动类
@SpringBootApplication
@EnableEurekaClient //标注为 Client 类或者 @EnableDiscoveryClient
//(兼容性更好 @EnableDiscoveryClient)
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class,args);}
}
  1. Controller中作出区分
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/find/{id}")public User findOneById(@PathVariable(value = "id")Integer id){User user = userService.findOneById(id);user.setName("user-provider");return user;}
}

第三步、创建服务提供者–注册服务2

  1. 创建maven工程,引入jar包
<!--依赖包-->
<dependencies><!--JPA包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!--web起步包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--MySQL驱动包--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--eureka-client依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency></dependencies>
  1. 创建 application.yml 文件
server:port: 18083
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: rooturl: jdbc:mysql://127.0.0.1:3306/springcloud?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTCapplication:name: user-provider #服务的名字,不同的应用,名字不同,如果是集群,名字需要相同#指定eureka服务地址
eureka:client:service-url:# EurekaServer的地址defaultZone: http://localhost:7001/eureka
  1. 启动类
@SpringBootApplication
@EnableEurekaClient //标注为 Client 类或者 @EnableDiscoveryClient
//(兼容性更好 @EnableDiscoveryClient)
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class,args);}
}
  1. Controller中作出区分
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/find/{id}")public User findOneById(@PathVariable(value = "id")Integer id){User user = userService.findOneById(id);user.setName("user-provider-demo01");//区分两个服务器return user;}
}

第四步、创建服务消费者–发现服务

  1. 创建maven工程,引入jar包
!--依赖包-->
<dependencies><!--web起步依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--eureka-client依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
</dependencies>
  1. 创建 application.yml 文件
server:port: 18082
spring:application:name: user-consumer   #服务名字
#指定eureka服务地址
eureka:client:service-url:# EurekaServer的地址defaultZone: http://localhost:7001/eureka
  1. 启动类
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}/*** 开启负载均衡* @return*/@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}
}
  1. Controller
@RestController
@RequestMapping("/consumer")
public class ConsumerController {@Autowiredprivate RestTemplate restTemplate;@GetMapping(value = "/{id}")public User queryById(@PathVariable(value = "id")Integer id){String url = "http://user-provider/user/find/"+id;return restTemplate.getForObject(url,User.class);}
}

测试
启动并访问测试 http://localhost:18082/consumer/1 ,可以发现,数据会在2个服务之间轮询切换。

③、Spring Cloud Hystrix(熔断器)

雪崩机制详解

什么是雪崩效应?

分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。

对大部分电商和快递公司来说,每年年底(Q4季度)由于双11等大促活动的存在,将面对大量的用户流量,尤其是属于大促的那几天,无论是用户的商品订单还是物流订单,都将是平时的3倍以上。

如果这个时候,单个服务出现问题,调用这个服务就出现线程阻塞,此时若有大量的请求涌入,容器的线程资源就会被消耗完毕导致服务瘫痪。

如下图,对于同步调用,当库存服务不可用时,商品服务请求线程被阻塞,当有大批量请求调用库存服务时,最终可能导致整个商品服务资源耗尽,无法继续对外提供服务。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成不可估量的严重后果,这就是常说的服务故障的“雪崩效应”。

熔断器状态机有3个状态:

熔断器有三个状态 CLOSED、 OPEN、HALF_OPEN 熔断器默认关闭状态,当触发熔断后状态变更为 OPEN,在等待到指定的时间,Hystrix会放请求检测服务是否开启,这期间熔断器会变为HALF_OPEN 半开启状态,熔断探测服务可用则继续变更为 CLOSED关闭熔断器。

① Closed:关闭状态,所有请求正常访问② Open:打开状态,所有请求都会被降级。
Hystrix会对请求情况计数,当一定时间失败请求百分比达到阈值(极限值),则触发熔断,断路器完全关闭,默认失败比例的阈值是50%,请求次数最低不少于20次③ Half Open:半开状态
Open状态不是永久的,打开一会后会进入休眠时间(默认5秒)。休眠时间过后会进入半开状态。
半开状态:熔断器会判断下一次请求的返回状况,如果成功,熔断器切回closed状态。如果失败,熔断器切回open状态。


熔断 三种 状态 流程图:

熔断器的核心:线程隔离和服务降级。

1.线程隔离:是指 Hystrix 为每个依赖服务调用一个小的线程池,如果线程池用尽,调用立即被拒绝,默认不采用排队。2.服务降级(兜底方法):优先保证核心服务,而非核心服务不可用或弱可用。触发 Hystrix 服务降级的情况:线程池已满、请求超时。

代码实现

  1. pom.xml文件中添加 Hystrix 需要的 jar 包
<!--熔断器-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
  1. Controller 中的配置及实现
/**
1、在类前添加注释  @DefaultProperties
2、编写全局服务降级处理方法
*/
@DefaultProperties(defaultFallback = "defaultFallback")
public User defaultFallback(){User user = new User();user.setUsername("Default---服务降级,默认处理");return user;
}3、将 @HystrixCommand 加在需要熔断的方法上。

④、Spring Cloud Feign (伪装)

概念

 Feign可以把HTTP 的请求进行隐藏,伪装成类似 SpringMVC 的 Controller一样。你不用再自己拼接 url,拼接参数等等操作,一切都交给 Feign 去做。

特性

 Ⅰ、集成Ribbon的负载均衡功能Ⅱ、集成了Hystrix的熔断器功能Ⅲ、支持请求压缩Ⅳ、大大简化了远程调用的代码,同时功能还增强啦Ⅴ、Feign以更加优雅的方式编写远程调用代码,并简化重复代码

代码实现

(1)导入依赖

在user-consumer中添加依赖

<!--配置feign-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

(2)创建Feign客户端

//@FeignClient(value = "要调用微服务的名字")
@FeignClient(value = "user-provider")
public interface UserClient {/**** 根据ID查询用户信息* @param id* @return*/@RequestMapping(value = "/user/find/{id}")User findById(@PathVariable(value = "id") Integer id);
}

解释:

 Feign会通过动态代理,帮我们生成实现类。注解@FeignClient声明Feign的客户端,注解value指明服务名称接口定义的方法,采用SpringMVC的注解。Feign会根据注解帮我们生成URL地址注解@RequestMapping中的/user,不要忘记。因为Feign需要拼接可访问地址

(3)控制层

@RestController
@RequestMapping(value = "/feign")
public class ConsumerFeignController {@Autowiredprivate UserClient userClient;@RequestMapping(value = "/{id}")public User queryById(@PathVariable(value = "id")Integer id){return userClient.findById(id);}
}

(4)开启Feign:

 启动类中加入注解 --@EnableFeignClients(basePackages = {"com.atguigu.feign"})
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.atguigu.feign"})
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}/*** 开启负载均衡* @return*/@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}}

(5) 测试

 请求http://localhost:18082/feign/2,效果如下:

Feign内置的ribbon默认设置了请求超时时长,默认是1000,可以修改

ribbon内部有重试机制,一旦超时,会自动重新发起请求。如果不希望重试可以关闭配置:

# 修改服务地址轮询策略,默认是轮询,配置之后变随机
user-provider:ribbon:#轮询NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRuleConnectTimeout: 1000 # 连接超时时间 没有连接上ReadTimeout: 2000 # 数据读取超时时间 连接上了,连上之后开始计时,但读取数据需要花费很长时间MaxAutoRetries: 1 # 最大重试次数(第一个服务)在第一次连接超时之后,在重新连接一次MaxAutoRetriesNextServer: 0 # 最大重试下一个服务次数(集群的情况才会用到)OkToRetryOnAllOperations: false # 是否所有操作都进行重试

⑤、Spring Cloud Gateway(网关)

概念

Spring Cloud Gateway 作为SpringCloud生态系统中的网关,目标是替代Netflix Zuul。Gateway不仅提供统一路由方式,并且基于Filter链的方式提供网关的基本功能。

核心

Ⅰ、Route(路由):路由是网关的基本单元,由ID、URI、一组Predicate、一组Filter组成,根据Predicate进行匹配转发。Ⅱ、Predicate(谓语、断言):路由转发的判断条件Ⅲ、Filter(过滤器):过滤器是路由转发请求时所经过的过滤逻辑,可用于修改请求、响应内容。

四、Spring Cloud 小结

1、Spring Cloud Eureka :服务发现

将各个微服务注册到 Eureka Server 上,通过心跳检测、客户端缓存等机制,确保了系统的高可用性、灵活性和可维护性。

2、Spring Cloud Ribbon :客户端的负载均衡

提供负载均衡机制,Ribbon可以基于某种均衡算法(轮询、加权响应时间、随机和区域感知轮询等)自动帮助服务消费者请求。

3、Spring Cloud Hystrix :熔断器

实现服务熔断降级处理,保护微服务,防止雪崩效应发生。

4、Spring Cloud Feign :伪装

不再使用拼接URL的方式实现远程调用,以接口调用的方式实现远程调用,简化了远程调用的实现方式,增强了远程调用功能。

5、Spring Cloud Geteway :网关

为微服务架构提供一种简单有效统一的API路由管理方式,可以在网关中实现微服务鉴权、安全控制、请求监控、限流等。

初识Spring Cloud 之 五大神兽相关推荐

  1. Spring Cloud 架构 五大神兽的功能

    什么是微服务 微服务的概念源于2014年3月Martin Fowler所写的一篇文章"Microservices". 微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服 ...

  2. Spring Cloud中五大神兽总结(Eureka/Ribbon/Feign/Hystrix/zuul)

    一.常用的模块 1.Eureka Eureka是Netflix的一个子模块,也是核心模块之一.Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移.服务注册与发现对于 ...

  3. Spring Cloud Netflix五大组件简介

    微服务与微服务架构 微服务的优缺点 优点 缺点 Dubbo与Spring Cloud Spring Cloud Netflix Eureka Eureka的自我保护机制 Eureka和ZooKeepe ...

  4. springcloud的简单使用_微服务架构:初识Spring Cloud

    现在无论大小公司,都会讲究微服务设计,无论应用大小,都会进行微服务架构,面试的时候,也会把微服务当成必谈的知识点.那么什么是微服务呢? "微服务"一词源于Martin Fowler ...

  5. Spring Cloud文档阅读笔记-初识Spring Cloud(对Spring Cloud初步了解)

    首先要知道的是Spring Cloud是微服务架构. 微服务架构是一种架构模式,它将单一的应用程序划分成一组很小的服务,服务之间相互协调.互相配合.每个服务都运行在独立的进程中,服务与服务间采用轻量级 ...

  6. 手把手,嘴对嘴教你Spring Cloud 微服务实战 -- 初识Spring Cloud

    Spring Cloud 简介 摘自百度百科: Spring Cloud是一系列框架的有序集合.它利用SpringBoot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消 ...

  7. 系统架构演变到Spring Cloud

    目录 1. 系统架构演变 1.1. 集中式架构 1.2. 垂直拆分 1.3. 分布式服务 1.4. 面向服务架构(SOA) 1.5. 微服务架构 2. 服务调用方式 2.1. RPC和HTTP 2.2 ...

  8. 轻松搞定 Spring Cloud 2.x 微服务全家桶

    研究了一段时间 Spring Boot 了准备向 Spring Cloud 进发,公司架构和项目也全面拥抱了 Spring Cloud.在使用了一段时间后发现 Spring Cloud 从技术架构上降 ...

  9. 手把手,嘴对嘴教你Spring Cloud 微服务实战 -- 前言

    Spring Cloud 总结 博主接触到Spring Cloud 大概已经一年多了,当时Spring Cloud微服务框架已经是潮流了,不会一点都不好意思出去面试.并且主流技术基本上都在谈论微服务, ...

最新文章

  1. Linq之延迟加载特性
  2. (0006) iOS 开发之JavaScriptCore 实现UIWebView和HTML的交互
  3. Linux之ping命令使用详解—网络故障定位(六)
  4. optee3.14中MMU页表查询的所需配置--深入解读
  5. 【星球知识卡片】换脸算法和人脸驱动都有哪些核心技术,如何对其长期深入学习...
  6. 选择将正确答案的序号填在括号里_小学四年级数学第五单元训练题,答案非常详细,见过的都保存了...
  7. 《网易编程题》计算糖果
  8. [Yii Framework] 数据库查询
  9. linux好用的编译器,推荐几款Linux下比Notepad++好的编辑器软件
  10. Yii 2 美化 url
  11. 混淆 php,开发简单的PHP混淆器与解混淆器
  12. 微信开发者工具整个是个浏览器
  13. wpsppt放映时间_wps演示怎么调整放映速度?
  14. 高等数学——微分方程
  15. 怎么同时给多个 Word 文档批量添加自定义的文字和图片水印
  16. meta标签详解(name、http-equiv、scheme、charset、各浏览器常用meta标签、常见移动端meta标签)、viewport详解
  17. java chmod 777_尽管使用chmod 777,但java.io.FileNotFoundException(权限被拒绝)
  18. JavaMail实现发送邮件程序
  19. JavaScript里面的“类”
  20. c语言visit_数据结构(c语言)——入门数据结构的世界:顺序线性表(一)

热门文章

  1. 【新华三网络工程师】H3C如何配置三层组网技术
  2. 框架模式MVC与MVP在Android中的应用
  3. 2021-03-17T23:47:55.978+08:00 UTC时间转换
  4. 【Java基础】基础概念与常识
  5. 远程访问MySql数据库
  6. MAC下搭建Hexo博客
  7. FastDFS,Redis,Solr,ActiveMQ核心技术整合二(1)
  8. MySQL事务及实现原理
  9. 全网最全持续集成接口自动化-jmeter+ant+jenkins
  10. Android adb启动错误,使用adb shell启动Android应用程序时出现错误“活动类不存在”...