当前位置: 首页 > news >正文

个人网站模板怎么做免费seo排名网站

个人网站模板怎么做,免费seo排名网站,个人网页设计与制作论文结束语,wordpress左边导航栏文章目录 一#xff0c;概述二#xff0c;实现过程三#xff0c;项目源码1. 源码放送#xff1a;2. 部署方式 四#xff0c;功能演示五#xff0c;其他 一#xff0c;概述 一般来说#xff0c;提到负载均衡#xff0c;大家一般很容易想到浏览器 - NGINX - 反… 文章目录 一概述二实现过程三项目源码1. 源码放送2. 部署方式 四功能演示五其他 一概述 一般来说提到负载均衡大家一般很容易想到浏览器 - NGINX - 反向代理多个Tomcat这样的架构图——业界管这种负载均衡模式叫“服务器端负载均衡”因为此种模式下负载均衡算法是NGINX提供的而NGINX部署在服务器端。 本文所讲的Ribbon则是一个客户端侧负载均衡组件——通俗地说就是集成在客户端服务消费者一侧并提供负载均衡算法的一个组件。Ribbon是Netflix发布的负载均衡器它可以帮我们控制HTTP和TCP客户端的行为。只需为Ribbon配置服务提供者地址列表Ribbon就可基于负载均衡算法计算出要请求的目标服务地址。Ribbon默认为我们提供了很多的负载均衡算法例如轮询、随机、响应时间加权等。 二实现过程 一般情况下负载均衡组件Ribbon和微服务注册中心Eureka是配合使用的。 为了在非springCloud微服务项目中使用Ribbon的客户端负载均衡能力我们可以按如下步骤实现 定义服务的被调用方Client编写webApi接口定义服务的调用方Cousumer调用webApi接口定义网关模块Gateway通过定义路由的方式重新定义webApi接口路径并引入Ribbon客户端负载均衡将步骤2中的WebApi地址切换为网关模块路由接口地址从而使原来的webApi地址具有了客户端负载均衡功能使用docker部署Client多实例、Gateway并在编排文件中使用服务名代替客户端列表地址解耦Cousumer与Client之间的代码接口。 三项目源码 1. 源码放送 https://gitee.com/00fly/microservice-all-in-one/tree/master/ribbon-demo 或者使用下面的备份文件恢复成原始的项目代码 如何恢复请移步查阅神奇代码恢复工具 //goto docker-auto-ip\docker-compose.yml version: 3.8 services:#gatewayribbon-gateway:image: registry.cn-shanghai.aliyuncs.com/00fly/ribbon-gateway:0.0.1container_name: ribbon-gatewaydeploy:resources:limits:cpus: 1memory: 300Mreservations:memory: 200Mports:- 8085:8080environment:USER_SERVERS: ribbon-user-0:8081,ribbon-user-1:8081MOVIE_SERVERS: ribbon-movie:8082restart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: 1#client01ribbon-user-0:image: registry.cn-shanghai.aliyuncs.com/00fly/ribbon-user:0.0.1container_name: ribbon-user-0deploy:resources:limits:cpus: 1memory: 300Mreservations:memory: 200Mrestart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: 1#client02ribbon-user-1:image: registry.cn-shanghai.aliyuncs.com/00fly/ribbon-user:0.0.1container_name: ribbon-user-1deploy:resources:limits:cpus: 1memory: 300Mreservations:memory: 200Mrestart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: 1ribbon-movie:image: registry.cn-shanghai.aliyuncs.com/00fly/ribbon-movie:0.0.1container_name: ribbon-moviedeploy:resources:limits:cpus: 1memory: 300Mreservations:memory: 200Menvironment:USER_API_URL: ribbon-gateway:8080/user/restart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: 1 //goto docker-auto-ip\restart.sh #!/bin/bash docker-compose down \ docker-compose --compatibility up -d \ docker stats //goto docker-auto-ip\stop.sh #!/bin/bash docker-compose down //goto docker-fix-ip\docker-compose.yml version: 3.8 networks:default:name: devopsdriver: bridgeipam:config:- subnet: 172.88.88.0/24 services:#gatewayribbon-gateway:image: registry.cn-shanghai.aliyuncs.com/00fly/ribbon-gateway:0.0.1container_name: ribbon-gatewaydeploy:resources:limits:cpus: 1memory: 300Mreservations:memory: 200Mports:- 8085:8080environment:MOVIE_SERVERS: 172.88.88.101:8082USER_SERVERS: 172.88.88.200:8081,172.88.88.201:8081restart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: 1networks:default:ipv4_address: 172.88.88.100#client01ribbon-user-0:image: registry.cn-shanghai.aliyuncs.com/00fly/ribbon-user:0.0.1container_name: ribbon-user-0deploy:resources:limits:cpus: 1memory: 300Mreservations:memory: 200Mrestart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: 1networks:default:ipv4_address: 172.88.88.200#client02ribbon-user-1:image: registry.cn-shanghai.aliyuncs.com/00fly/ribbon-user:0.0.1container_name: ribbon-user-1deploy:resources:limits:cpus: 1memory: 300Mreservations:memory: 200Mrestart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: 1networks:default:ipv4_address: 172.88.88.201ribbon-movie:image: registry.cn-shanghai.aliyuncs.com/00fly/ribbon-movie:0.0.1container_name: ribbon-moviedeploy:resources:limits:cpus: 1memory: 300Mreservations:memory: 200Menvironment:USER_API_URL: http://172.88.88.100:8080/user/restart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: 1networks:default:ipv4_address: 172.88.88.101 //goto docker-fix-ip\restart.sh #!/bin/bash docker-compose down \ docker-compose --compatibility up -d \ docker stats //goto docker-fix-ip\stop.sh #!/bin/bash docker-compose down //goto docker-scale\docker-compose.yml version: 3.8 services:#gatewayribbon-gateway:image: registry.cn-shanghai.aliyuncs.com/00fly/ribbon-gateway:0.0.1container_name: ribbon-gatewaydeploy:resources:limits:cpus: 1memory: 300Mreservations:memory: 200Mports:- 8085:8080environment:USER_SERVERS: ribbon-user:8081MOVIE_SERVERS: ribbon-movie:8082restart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: 1#clientribbon-user:image: registry.cn-shanghai.aliyuncs.com/00fly/ribbon-user:0.0.1deploy:resources:limits:cpus: 1memory: 300Mreservations:memory: 200Mrestart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: 1ribbon-movie:image: registry.cn-shanghai.aliyuncs.com/00fly/ribbon-movie:0.0.1deploy:resources:limits:cpus: 1memory: 300Mreservations:memory: 200Menvironment:USER_API_URL: ribbon-gateway:8080/user/restart: on-failurelogging:driver: json-fileoptions:max-size: 5mmax-file: 1 //goto docker-scale\restart.sh #!/bin/bash docker-compose down \ docker-compose --compatibility up -d --scale ribbon-user2 --scale ribbon-movie2 \ docker stats //goto docker-scale\stop.sh #!/bin/bash docker-compose down //goto pom.xml ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.itmuch.cloud/groupIdartifactIdribbon-all-in-one/artifactIdversion0.0.1/versionpackagingpom/packaging!-- 引入spring boot的依赖 --parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.2.6.RELEASE/versionrelativePath //parentmodulesmoduleribbon-gateway/modulemoduleribbon-movie/modulemoduleribbon-user/module/modulespropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.build.timestamp.formatyyyyMMdd-HH/maven.build.timestamp.formatdocker.hubregistry.cn-shanghai.aliyuncs.com/docker.hubjava.version1.8/java.versiondocker.plugin.version1.2.2/docker.plugin.versiondocker.image.prefix00fly/docker.image.prefixspring.cloud.versionHoxton.SR6/spring.cloud.versionknife4j.version2.0.8/knife4j.versionskipTeststrue/skipTests/propertiesdependencyManagementdependencies!-- 引入spring cloud的依赖 --dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-dependencies/artifactIdversion${spring.cloud.version}/versiontypepom/typescopeimport/scope/dependencydependencygroupIdcom.github.xiaoymin/groupIdartifactIdknife4j-spring-boot-starter/artifactIdversion${knife4j.version}/version/dependencydependencygroupIdcom.github.xiaoymin/groupIdartifactIdknife4j-micro-spring-boot-starter/artifactIdversion${knife4j.version}/version/dependency/dependencies/dependencyManagementbuildpluginManagementpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdexecutionsexecutiongoalsgoalrepackage/goal/goals/execution/executions/plugin!-- 添加docker-maven插件 --plugingroupIdio.fabric8/groupIdartifactIddocker-maven-plugin/artifactIdversion0.40.3/versionexecutionsexecutionphasepackage/phasegoalsgoalbuild/goal!--goalpush/goal--!--goalremove/goal--/goals/execution/executionsconfiguration!-- 连接到带docker环境的linux服务器编译image --!--dockerHosthttp://192.168.182.10:2375/dockerHost--!-- Docker 推送镜像仓库地址 --pushRegistry${docker.hub}/pushRegistryimagesimage!--推送到私有镜像仓库镜像名需要添加仓库地址 --name${docker.hub}/00fly/${project.artifactId}:${project.version}/name!--定义镜像构建行为 --builddockerFileDir${project.basedir}/dockerFileDir/build/image/imagesauthConfig!--认证配置,用于私有镜像仓库registry认证 --username${docker.username}/usernamepassword${docker.password}/password/authConfig/configuration/plugin/plugins/pluginManagement/build /project //goto ribbon-gateway\Dockerfile #基础镜像 FROM adoptopenjdk/openjdk8-openj9:alpine-slimCOPY wait-for.sh / RUN chmod x /wait-for.sh \ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime echo Asia/Shanghai /etc/timezone#引入运行包 COPY target/*.jar /app.jar#指定交互端口 EXPOSE 8080CMD [--server.port8080]#项目的启动方式 ENTRYPOINT [java, -Djava.security.egdfile:/dev/./urandom, -Xshareclasses, -Xquickstart, -jar, /app.jar] //goto ribbon-gateway\pom.xml ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentgroupIdcom.itmuch.cloud/groupIdartifactIdribbon-all-in-one/artifactIdversion0.0.1/version/parentmodelVersion4.0.0/modelVersionartifactIdribbon-gateway/artifactIdpackagingjar/packagingdependenciesdependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactIdexclusionsexclusiongroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-logging/artifactId/exclusion/exclusions/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-log4j2/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-netflix-ribbon/artifactId/dependency!-- 集成 knife4j --dependencygroupIdcom.github.xiaoymin/groupIdartifactIdknife4j-spring-boot-starter/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency/dependenciesbuildfinalName${project.artifactId}/finalNamepluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/pluginplugingroupIdio.fabric8/groupIdartifactIddocker-maven-plugin/artifactId/plugin/plugins/build /project //goto ribbon-gateway\src\main\java\com\fly\gateway\config\SwaggerHeaderFilter.java package com.fly.gateway.config;import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.server.ServerWebExchange;/*** author fsl* description: SwaggerHeaderFilter* date 2019-06-0310:47*/ Component public class SwaggerHeaderFilter extends AbstractGatewayFilterFactoryObject {private static final String HEADER_NAME X-Forwarded-Prefix;private static final String URI /v2/api-docs;/*** 网关过滤器*/Overridepublic GatewayFilter apply(Object config){return (exchange, chain) - {ServerHttpRequest request exchange.getRequest();String path request.getURI().getPath();if (!StringUtils.endsWithIgnoreCase(path, URI)){return chain.filter(exchange);}String basePath path.substring(0, path.lastIndexOf(URI));ServerHttpRequest newRequest request.mutate().header(HEADER_NAME, basePath).build();ServerWebExchange newExchange exchange.mutate().request(newRequest).build();return chain.filter(newExchange);};} } //goto ribbon-gateway\src\main\java\com\fly\gateway\config\SwaggerResourceConfig.java package com.fly.gateway.config;import java.util.ArrayList; import java.util.List;import org.springframework.cloud.gateway.config.GatewayProperties; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.support.NameUtils; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component;import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import springfox.documentation.swagger.web.SwaggerResource; import springfox.documentation.swagger.web.SwaggerResourcesProvider;/**** 聚合各个服务的swagger接口*/ Slf4j Component Primary AllArgsConstructor public class SwaggerResourceConfig implements SwaggerResourcesProvider {/*** 网关路由*/private final RouteLocator routeLocator;private final GatewayProperties gatewayProperties;Overridepublic ListSwaggerResource get(){ListSwaggerResource resources new ArrayList();ListString routes new ArrayList();routeLocator.getRoutes().subscribe(route - routes.add(route.getId()));gatewayProperties.getRoutes().stream().filter(routeDefinition - routes.contains(routeDefinition.getId())).forEach(route - {route.getPredicates().stream().filter(predicateDefinition - (Path).equalsIgnoreCase(predicateDefinition.getName())).forEach(predicateDefinition - resources.add(swaggerResource(route.getId(), predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX 0).replace(**, v2/api-docs))));});return resources;}private SwaggerResource swaggerResource(String name, String location){log.info(name:{},location:{}, name, location);SwaggerResource swaggerResource new SwaggerResource();swaggerResource.setName(name);swaggerResource.setLocation(location);swaggerResource.setSwaggerVersion(2.0);return swaggerResource;} } //goto ribbon-gateway\src\main\java\com\fly\gateway\GateWayApplication.java package com.fly.gateway;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication public class GateWayApplication {public static void main(String[] args){SpringApplication.run(GateWayApplication.class, args);} } //goto ribbon-gateway\src\main\java\com\fly\gateway\handler\SwaggerHandler.java package com.fly.gateway.handler;import java.util.Optional;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;import reactor.core.publisher.Mono; import springfox.documentation.swagger.web.SecurityConfiguration; import springfox.documentation.swagger.web.SecurityConfigurationBuilder; import springfox.documentation.swagger.web.SwaggerResourcesProvider; import springfox.documentation.swagger.web.UiConfiguration; import springfox.documentation.swagger.web.UiConfigurationBuilder;/*** swagger聚合接口* */ RestController public class SwaggerHandler {Autowired(required false)private SecurityConfiguration securityConfiguration;Autowired(required false)private UiConfiguration uiConfiguration;private final SwaggerResourcesProvider swaggerResources;public SwaggerHandler(SwaggerResourcesProvider swaggerResources){this.swaggerResources swaggerResources;}GetMapping(/swagger-resources/configuration/security)public MonoResponseEntitySecurityConfiguration securityConfiguration(){return Mono.just(new ResponseEntity(Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));}GetMapping(/swagger-resources/configuration/ui)public MonoResponseEntityUiConfiguration uiConfiguration(){return Mono.just(new ResponseEntity(Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));}GetMapping(/swagger-resources)public MonoResponseEntity? swaggerResources(){return Mono.just((new ResponseEntity(swaggerResources.get(), HttpStatus.OK)));} } //goto ribbon-gateway\src\main\resources\application.yml server:port: 8080 spring:application:name: ribbon-gatewaycloud:gateway:discovery:locator:lowerCaseServiceId: trueroutes:- id: ribbon-useruri: lb://ribbon-userpredicates:- Path/user/**filters:- StripPrefix1- id: ribbon-movieuri: lb://ribbon-moviepredicates:- Path/movie/**filters:- StripPrefix1ribbon-movie:ribbon:listOfServers: ${MOVIE_SERVERS:127.0.0.1:8082}ribbon-user:ribbon:listOfServers: ${USER_SERVERS:127.0.0.1:8081} //goto ribbon-gateway\wait-for.sh #!/bin/shTIMEOUT15 QUIET0echoerr() {if [ $QUIET -ne 1 ]; then printf %s\n $* 12; fi }usage() {exitcode$1cat USAGE 2 Usage:$cmdname host:port [-t timeout] [-- command args]-q | --quiet Do not output any status messages-t TIMEOUT | --timeouttimeout Timeout in seconds, zero for no timeout-- COMMAND ARGS Execute command with args after the test finishes USAGEexit $exitcode }wait_for() {for i in seq $TIMEOUT ; donc -z $HOST $PORT /dev/null 21result$?if [ $result -eq 0 ] ; thenif [ $# -gt 0 ] ; thenexec $fiexit 0fisleep 1doneecho Operation timed out 2exit 1 }while [ $# -gt 0 ] docase $1 in*:* )HOST$(printf %s\n $1| cut -d : -f 1)PORT$(printf %s\n $1| cut -d : -f 2)shift 1;;-q | --quiet)QUIET1shift 1;;-t)TIMEOUT$2if [ $TIMEOUT ]; then break; fishift 2;;--timeout*)TIMEOUT${1#*}shift 1;;--)shiftbreak;;--help)usage 0;;*)echoerr Unknown argument: $1usage 1;;esac doneif [ $HOST -o $PORT ]; thenechoerr Error: you need to provide a host and port to test.usage 2 fiwait_for $ //goto ribbon-movie\Dockerfile #基础镜像 FROM adoptopenjdk/openjdk8-openj9:alpine-slimCOPY wait-for.sh / RUN chmod x /wait-for.sh \ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime echo Asia/Shanghai /etc/timezone#引入运行包 COPY target/*.jar /app.jar#指定交互端口 EXPOSE 8082CMD [--server.port8082]#项目的启动方式 ENTRYPOINT [java, -Djava.security.egdfile:/dev/./urandom, -Xshareclasses, -Xquickstart, -jar, /app.jar] //goto ribbon-movie\pom.xml ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentgroupIdcom.itmuch.cloud/groupIdartifactIdribbon-all-in-one/artifactIdversion0.0.1/version/parentmodelVersion4.0.0/modelVersionartifactIdribbon-movie/artifactIdpackagingjar/packagingdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdexclusionsexclusiongroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-logging/artifactId/exclusion/exclusions/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-log4j2/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-webflux/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-netflix-hystrix/artifactId/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactId/dependency!-- 使用Apache HttpClient替换Feign原生httpclient --dependencygroupIdio.github.openfeign/groupIdartifactIdfeign-okhttp/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdscopeprovided/scope/dependency!-- 集成 knife4j --dependencygroupIdcom.github.xiaoymin/groupIdartifactIdknife4j-spring-boot-starter/artifactId/dependency/dependenciesbuildfinalName${project.artifactId}/finalNamepluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/pluginplugingroupIdio.fabric8/groupIdartifactIddocker-maven-plugin/artifactId/plugin/plugins/build /project //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\ConsumerMovieApplication.java package com.itmuch.cloud.study;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cloud.openfeign.EnableFeignClients;EnableCaching EnableFeignClients SpringBootApplication public class ConsumerMovieApplication {public static void main(String[] args){SpringApplication.run(ConsumerMovieApplication.class, args);} } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\core\config\Knife4jConfig.java package com.itmuch.cloud.study.core.config;import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;import io.swagger.annotations.ApiOperation; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;/*** Knife4j配置**/ Configuration EnableKnife4j EnableSwagger2WebMvc public class Knife4jConfig {Value(${knife4j.enable:true})private boolean enable;/*** 开发、测试环境接口文档打开* * return* see [类、类#方法、类#成员]*/BeanDocket createRestApi(){return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).enable(enable).select().apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any()) // 包下的类生成接口文档.build();}private ApiInfo apiInfo(){return new ApiInfoBuilder().title(movie模块API).description(接口文档).termsOfServiceUrl(http://00fly.online/).version(1.0.0).build();} } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\core\config\RibbonConfiguration.java //package com.itmuch.cloud.study.core.config; // //import org.springframework.context.annotation.Bean; //import org.springframework.context.annotation.Configuration; // //import com.netflix.loadbalancer.IRule; //import com.netflix.loadbalancer.RandomRule; // ///** // * 该类为Ribbon的配置类 注意该类不应该在主应用程序上下文的ComponentScan 中。 // * // */ //Configuration //public class RibbonConfiguration //{ // Bean // IRule ribbonRule() // { // // 负载均衡规则改为随机 // return new RandomRule(); // } //} //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\core\config\TestConfiguration.java //package com.itmuch.cloud.study.core.config; // //import org.springframework.cloud.netflix.ribbon.RibbonClient; //import org.springframework.context.annotation.Configuration; // ///** // * 使用RibbonClient为特定name的Ribbon Client自定义配置. 使用RibbonClient的configuration属性指定Ribbon的配置类. br // * 可参考的示例 http://spring.io/guides/gs/client-side-load-balancing/ // * // */ //Configuration //RibbonClient(name microservice-ribbon-user, configuration RibbonConfiguration.class) //public class TestConfiguration //{ //} //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\core\config\WebMvcConfig.java package com.itmuch.cloud.study.core.config;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** * mvc配置* * author 00fly* version [版本号, 2021年4月23日]* see [相关类/方法]* since [产品/模块版本]*/ Configuration public class WebMvcConfig implements WebMvcConfigurer {/*** param registry*/Overridepublic void addViewControllers(final ViewControllerRegistry registry){registry.addViewController(/).setViewName(doc.html);} } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\core\utils\JsonBeanUtils.java package com.itmuch.cloud.study.core.utils;import java.io.IOException;import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper;/*** JsonBean转换工具* * author 00fly**/ public class JsonBeanUtils {private static ObjectMapper objectMapper new ObjectMapper();/*** bean转json字符串* * param bean* return* throws IOException*/public static String beanToJson(Object bean)throws IOException{String jsonText objectMapper.writeValueAsString(bean);return objectMapper.readTree(jsonText).toPrettyString();}/*** bean转json字符串* * param bean* param pretty 是否格式美化* return* throws IOException*/public static String beanToJson(Object bean, boolean pretty)throws IOException{if (pretty){return beanToJson(bean);}String jsonText objectMapper.writeValueAsString(bean);return objectMapper.readTree(jsonText).toString();}/*** json字符串转bean* * param jsonText* return* throws IOException*/public static T T jsonToBean(String jsonText, ClassT clazz)throws IOException{return objectMapper.readValue(jsonText, clazz);}/*** json字符串转bean* * param jsonText* return* throws IOException*/public static T T jsonToBean(String jsonText, JavaType javaType)throws IOException{return objectMapper.readValue(jsonText, javaType);}/*** json字符串转bean* * param jsonText* param clazz* param ingoreError 是否忽略无法识别字段* return* throws IOException*/public static T T jsonToBean(String jsonText, ClassT clazz, boolean ingoreError)throws IOException{objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, !ingoreError);return objectMapper.readValue(jsonText, clazz);}/*** json字符串转bean* * param jsonText* return* throws IOException*/public static T T jsonToBean(String jsonText, TypeReferenceT typeRef)throws IOException{return objectMapper.readValue(jsonText, typeRef);} } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\user\controller\DataPushController.java package com.itmuch.cloud.study.user.controller;import java.io.IOException; import java.util.List; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit;import javax.annotation.PostConstruct;import org.apache.commons.lang3.RandomUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;import com.itmuch.cloud.study.core.utils.JsonBeanUtils; import com.itmuch.cloud.study.user.entity.Article; import com.itmuch.cloud.study.user.service.DataService; import com.itmuch.cloud.study.user.service.SSEServer;import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j;Slf4j Api(tags DataPush模块) RestController public class DataPushController {long init 0L;AutowiredDataService dataService;PostConstructprivate void init(){log.info(Server-Sent Events start);new ScheduledThreadPoolExecutor(2).scheduleAtFixedRate(() - {long now (init RandomUtils.nextInt(5, 10)) % 101;SSEServer.batchSendMessage(String.valueOf(init));if (now init){try{// 随机选择2个返回访问量小的ListArticle articles dataService.getArticles();int length articles.size();Article article001 articles.get(RandomUtils.nextInt(0, length));Article article002 articles.get(RandomUtils.nextInt(0, length));SSEServer.batchSendMessage(json, JsonBeanUtils.beanToJson(article001.getViewCount() article002.getViewCount() ? article002 : article001, false));}catch (IOException e){}}init now;}, 2000, 1000, TimeUnit.MILLISECONDS);}CrossOriginGetMapping(/sse/connect/{userId})public SseEmitter connect(PathVariable String userId){return SSEServer.connect();} } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\user\controller\MovieController.java package com.itmuch.cloud.study.user.controller;import java.net.InetAddress; import java.net.UnknownHostException;import javax.annotation.PostConstruct;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController;import com.itmuch.cloud.study.user.entity.User; import com.itmuch.cloud.study.user.feign.UserFeignClient;import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation;Api(tags movie模块) RestController public class MovieController {String serverIp;Autowiredprivate UserFeignClient userFeignClient;PostConstructprivate void init(){try{serverIp InetAddress.getLocalHost().getHostAddress();}catch (UnknownHostException e){}}ApiOperation(查询用户)GetMapping(/user/{id})public User findById(PathVariable Long id){// 带出serverIp方便判断数据来源容器User user this.userFeignClient.findById(id);if (user.getId() 0){user.setName(user.getName() in server serverIp);}return user;} } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\user\entity\Article.java package com.itmuch.cloud.study.user.entity;import lombok.Data;Data public class Article {String title;String url;Long viewCount; } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\user\entity\BlogData.java package com.itmuch.cloud.study.user.entity;import lombok.Data;Data public class BlogData {private Record data; } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\user\entity\Record.java package com.itmuch.cloud.study.user.entity;import java.util.List;import lombok.Data;Data public class Record {private ListArticle list; } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\user\entity\User.java package com.itmuch.cloud.study.user.entity;import java.math.BigDecimal;import lombok.Data;Data public class User {private Long id;private String username;private String name;private Integer age;private BigDecimal balance; } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\user\feign\UserFeignClient.java package com.itmuch.cloud.study.user.feign;import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable;import com.itmuch.cloud.study.user.entity.User;FeignClient(name microservice-ribbon-user, url ${user.api.url:127.0.0.1:8081}, fallback FeignClientFallback.class) public interface UserFeignClient {GetMapping(/{id})public User findById(PathVariable(id) Long id); }/*** 回退类FeignClientFallback需实现Feign Client接口FeignClientFallback也可以是public class没有区别* */ Component class FeignClientFallback implements UserFeignClient {Overridepublic User findById(Long id){User user new User();user.setId(-1L);user.setUsername(默认用户);return user;} } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\user\service\DataService.java package com.itmuch.cloud.study.user.service;import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.List;import org.springframework.cache.annotation.Cacheable; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient;import com.itmuch.cloud.study.core.utils.JsonBeanUtils; import com.itmuch.cloud.study.user.entity.Article; import com.itmuch.cloud.study.user.entity.BlogData;import lombok.extern.slf4j.Slf4j;/*** DataService*/ Slf4j Service public class DataService {WebClient webClient WebClient.builder().codecs(configurer - configurer.defaultCodecs().maxInMemorySize(-1)).build();/*** 获取Article数据列表* * return* throws IOException*/Cacheable(cacheNames data, key articles, sync true)public ListArticle getArticles()throws IOException{log.info(★★★★★★★★ getData from webApi ★★★★★★★★);String resp webClient.get().uri(https://00fly.online/upload/data.json).acceptCharset(StandardCharsets.UTF_8).accept(MediaType.APPLICATION_JSON).retrieve().bodyToMono(String.class).block();return JsonBeanUtils.jsonToBean(resp, BlogData.class, true).getData().getList();} } //goto ribbon-movie\src\main\java\com\itmuch\cloud\study\user\service\SSEServer.java package com.itmuch.cloud.study.user.service;import java.io.IOException; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer;import org.springframework.http.MediaType; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;import lombok.extern.slf4j.Slf4j;/*** Server-Sent Events BR* https://blog.csdn.net/hhl18730252820/article/details/126244274*/ Slf4j public class SSEServer {private static ListSseEmitter sseEmitters new CopyOnWriteArrayList();public static SseEmitter connect(){SseEmitter sseEmitter new SseEmitter(0L); // 设置超时时间0表示不过期默认是30秒超过时间未完成会抛出异常// 注册回调sseEmitter.onCompletion(completionCallBack(sseEmitter));sseEmitter.onError(errorCallBack(sseEmitter));sseEmitter.onTimeout(timeOutCallBack(sseEmitter));sseEmitters.add(sseEmitter);log.info(###### create new sse connect, count: {}, sseEmitters.size());return sseEmitter;}public static void batchSendMessage(String message){sseEmitters.forEach(it - {try{it.send(message, MediaType.APPLICATION_JSON);}catch (IOException e){log.error(send message error: {}, e.getMessage());remove(it);}});}/*** 指定name,发送message* * param name* param message 普通字符串或json数据*/public static void batchSendMessage(String name, String message){sseEmitters.forEach(it - {try{it.send(SseEmitter.event().name(name).data(message));}catch (IOException e){log.error(send message error: {}, e.getMessage());remove(it);}});}public static void remove(SseEmitter s){if (sseEmitters.contains(s)){sseEmitters.remove(s);log.info(###### remove SseEmitter, count: {}, sseEmitters.size());}}private static Runnable completionCallBack(SseEmitter s){return () - {log.info(结束连接);remove(s);};}private static Runnable timeOutCallBack(SseEmitter s){return () - {log.info(连接超时);remove(s);};}private static ConsumerThrowable errorCallBack(SseEmitter s){return throwable - {log.error(连接异常);remove(s);};} } //goto ribbon-movie\src\main\resources\application-ribbon.yml server:port: 8082 spring:application:name: ribbon-moviecache:type: simple#设置负载均衡参数 microservice-ribbon-user:ribbon:#配置规则NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule#配置地址宿主机ip映射端口或docker自定义网络指定地址#listOfServers: 172.22.208.1:8081,172.22.208.1:8091listOfServers: 172.88.88.200:8081,172.88.88.201:8081 feign:httpclient:enabled: true ribbon:ReadTimeout: 30000ConnectTimeout: 30000 logging:level:root: INFO //goto ribbon-movie\src\main\resources\application.yml server:port: 8082 spring:application:name: ribbon-moviecache:type: simple#feign.okhttp.enabled默认不开启 #从Spring Cloud Dalston开始Feign默认是不开启Hystrix的。 feign:okhttp:enabled: truehystrix:enabled: true logging:level:root: INFO //goto ribbon-movie\wait-for.sh #!/bin/shTIMEOUT15 QUIET0echoerr() {if [ $QUIET -ne 1 ]; then printf %s\n $* 12; fi }usage() {exitcode$1cat USAGE 2 Usage:$cmdname host:port [-t timeout] [-- command args]-q | --quiet Do not output any status messages-t TIMEOUT | --timeouttimeout Timeout in seconds, zero for no timeout-- COMMAND ARGS Execute command with args after the test finishes USAGEexit $exitcode }wait_for() {for i in seq $TIMEOUT ; donc -z $HOST $PORT /dev/null 21result$?if [ $result -eq 0 ] ; thenif [ $# -gt 0 ] ; thenexec $fiexit 0fisleep 1doneecho Operation timed out 2exit 1 }while [ $# -gt 0 ] docase $1 in*:* )HOST$(printf %s\n $1| cut -d : -f 1)PORT$(printf %s\n $1| cut -d : -f 2)shift 1;;-q | --quiet)QUIET1shift 1;;-t)TIMEOUT$2if [ $TIMEOUT ]; then break; fishift 2;;--timeout*)TIMEOUT${1#*}shift 1;;--)shiftbreak;;--help)usage 0;;*)echoerr Unknown argument: $1usage 1;;esac doneif [ $HOST -o $PORT ]; thenechoerr Error: you need to provide a host and port to test.usage 2 fiwait_for $ //goto ribbon-user\Dockerfile #基础镜像 FROM adoptopenjdk/openjdk8-openj9:alpine-slimCOPY wait-for.sh / RUN chmod x /wait-for.sh \ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime echo Asia/Shanghai /etc/timezone#引入运行包 COPY target/*.jar /app.jar#指定交互端口 EXPOSE 8081CMD [--server.port8081]#项目的启动方式 ENTRYPOINT [java, -Djava.security.egdfile:/dev/./urandom, -Xshareclasses, -Xquickstart, -jar, /app.jar] //goto ribbon-user\pom.xml ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentgroupIdcom.itmuch.cloud/groupIdartifactIdribbon-all-in-one/artifactIdversion0.0.1/version/parentmodelVersion4.0.0/modelVersionartifactIdribbon-user/artifactIdpackagingjar/packagingdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdexclusionsexclusiongroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-logging/artifactId/exclusion/exclusions/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-log4j2/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-jpa/artifactId/dependencydependencygroupIdcom.h2database/groupIdartifactIdh2/artifactId/dependency!-- 集成 knife4j --dependencygroupIdcom.github.xiaoymin/groupIdartifactIdknife4j-spring-boot-starter/artifactId/dependency/dependenciesbuildfinalName${project.artifactId}/finalNamepluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/pluginplugingroupIdio.fabric8/groupIdartifactIddocker-maven-plugin/artifactId/plugin/plugins/build /project //goto ribbon-user\src\main\java\com\itmuch\cloud\study\controller\UserController.java package com.itmuch.cloud.study.controller;import java.util.List; import java.util.Optional;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController;import com.itmuch.cloud.study.entity.User; import com.itmuch.cloud.study.repository.UserRepository;import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation;Api(tags user模块) RestController public class UserController {Autowiredprivate UserRepository userRepository;ApiOperation(查询用户)GetMapping(/{id:\\d})public OptionalUser findById(PathVariable Long id){return this.userRepository.findById(id);}ApiOperation(查询全部用户)GetMapping(getAll)public ListUser getAll(){return this.userRepository.findAll();} } //goto ribbon-user\src\main\java\com\itmuch\cloud\study\core\config\Knife4jConfig.java package com.itmuch.cloud.study.core.config;import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;import io.swagger.annotations.ApiOperation; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;/*** Knife4j配置**/ Configuration EnableKnife4j EnableSwagger2WebMvc public class Knife4jConfig {Value(${knife4j.enable:true})private boolean enable;/*** 开发、测试环境接口文档打开* * return* see [类、类#方法、类#成员]*/BeanDocket createRestApi(){return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).enable(enable).select().apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any()) // 包下的类生成接口文档.build();}private ApiInfo apiInfo(){return new ApiInfoBuilder().title(user模块API).description(接口文档).termsOfServiceUrl(http://00fly.online/).version(1.0.0).build();} } //goto ribbon-user\src\main\java\com\itmuch\cloud\study\core\config\WebMvcConfig.java package com.itmuch.cloud.study.core.config;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** * mvc配置* * author 00fly* version [版本号, 2021年4月23日]* see [相关类/方法]* since [产品/模块版本]*/ Configuration public class WebMvcConfig implements WebMvcConfigurer {/*** param registry*/Overridepublic void addViewControllers(final ViewControllerRegistry registry){registry.addViewController(/).setViewName(doc.html);} } //goto ribbon-user\src\main\java\com\itmuch\cloud\study\entity\User.java package com.itmuch.cloud.study.entity;import java.math.BigDecimal;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id;Entity public class User {public User(){}public User(Long id, String username, String name, Integer age, BigDecimal balance){this.id id;this.username username;this.name name;this.age age;this.balance balance;}IdGeneratedValue(strategy GenerationType.AUTO)private Long id;Columnprivate String username;Columnprivate String name;Columnprivate Integer age;Columnprivate BigDecimal balance;public Long getId(){return this.id;}public void setId(Long id){this.id id;}public String getUsername(){return this.username;}public void setUsername(String username){this.username username;}public String getName(){return this.name;}public void setName(String name){this.name name;}public Integer getAge(){return this.age;}public void setAge(Integer age){this.age age;}public BigDecimal getBalance(){return this.balance;}public void setBalance(BigDecimal balance){this.balance balance;}} //goto ribbon-user\src\main\java\com\itmuch\cloud\study\ProviderUserApplication.java package com.itmuch.cloud.study;import java.math.BigDecimal; import java.net.InetAddress; import java.util.stream.Stream;import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean;import com.itmuch.cloud.study.entity.User; import com.itmuch.cloud.study.repository.UserRepository;SpringBootApplication public class ProviderUserApplication {public static void main(String[] args){SpringApplication.run(ProviderUserApplication.class, args);}/*** 初始化用户信息 注Spring Boot2不能像1.x一样用spring.datasource.schema/data指定初始化SQL脚本否则与actuator不能共存br* 原因https://github.com/spring-projects/spring-boot/issues/13042br* https://github.com/spring-projects/spring-boot/issues/13539** param repository repo* return runner*/BeanApplicationRunner init(UserRepository repository){return args - {String ip InetAddress.getLocalHost().getHostAddress();int init (int)(System.currentTimeMillis() % 10);User user1 new User(1L, account1, 张三 from ip, init 20, new BigDecimal(100.00));User user2 new User(2L, account2, 李四 from ip, init 30, new BigDecimal(180.00));User user3 new User(3L, account3, 王五 from ip, init 40, new BigDecimal(280.00));Stream.of(user1, user2, user3).forEach(repository::save);};} } //goto ribbon-user\src\main\java\com\itmuch\cloud\study\repository\UserRepository.java package com.itmuch.cloud.study.repository;import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository;import com.itmuch.cloud.study.entity.User;Repository public interface UserRepository extends JpaRepositoryUser, Long { } //goto ribbon-user\src\main\resources\application.yml server:port: 8081 spring:application:name: ribbon-userjpa:generate-ddl: falseshow-sql: truehibernate:ddl-auto: create-drop logging:level:root: INFO //goto ribbon-user\wait-for.sh #!/bin/shTIMEOUT15 QUIET0echoerr() {if [ $QUIET -ne 1 ]; then printf %s\n $* 12; fi }usage() {exitcode$1cat USAGE 2 Usage:$cmdname host:port [-t timeout] [-- command args]-q | --quiet Do not output any status messages-t TIMEOUT | --timeouttimeout Timeout in seconds, zero for no timeout-- COMMAND ARGS Execute command with args after the test finishes USAGEexit $exitcode }wait_for() {for i in seq $TIMEOUT ; donc -z $HOST $PORT /dev/null 21result$?if [ $result -eq 0 ] ; thenif [ $# -gt 0 ] ; thenexec $fiexit 0fisleep 1doneecho Operation timed out 2exit 1 }while [ $# -gt 0 ] docase $1 in*:* )HOST$(printf %s\n $1| cut -d : -f 1)PORT$(printf %s\n $1| cut -d : -f 2)shift 1;;-q | --quiet)QUIET1shift 1;;-t)TIMEOUT$2if [ $TIMEOUT ]; then break; fishift 2;;--timeout*)TIMEOUT${1#*}shift 1;;--)shiftbreak;;--help)usage 0;;*)echoerr Unknown argument: $1usage 1;;esac doneif [ $HOST -o $PORT ]; thenechoerr Error: you need to provide a host and port to test.usage 2 fiwait_for $ 2. 部署方式 这边提供了3种docker部署方式 自动ip推荐固定ipdocker scale 水平扩展 分别对应上图的docker-auto-ip、docker-fix-ip、docker-scale 目录有兴趣的同学可以研究研究 四功能演示 http://124.71.129.204:8085/doc.html 五其他 此实例整合了gateway、ribbon、feign、hystrix、swagger 大家会发现hystrix熔断器起作用时并不从负载均衡中移除故障节点大家可以思考比较下hystrix和ribbon 异同 有任何问题和建议都可以向我提问讨论,大家一起进步谢谢! -over-
http://www.hkea.cn/news/14592107/

相关文章:

  • 想要接网站业务如何做怎么快速优化关键词排名
  • 未央免费做网站松江网站建设培训费用
  • 网站可信认证必须做东莞网站优化制作
  • 专业的建设网站网站的设计
  • 网站建设违约怎么投诉网站建设编辑
  • 站酷网怎么赚钱wordpress go页面如何使用
  • 手机如何网站腾讯企点怎么用
  • 杭州本地品牌网站建设收费百度seo在哪里
  • 做网站的软件名字全拼适合大学生做兼职的网站有哪些
  • 辛集建设局官方网站帝国cms能建设视频网站吗
  • 做网站要学一些什么本科自考需要考哪些科目
  • 基层建设检索网站wordpress优酷插件
  • 重庆网站制作教程陇南地网站seo
  • 建设一个网站需要注意哪些内容网站关键词代码怎么做
  • 贵阳网站建设企业免费网站建设设计制作公司
  • 怎么做网站系统建筑工程网络图计算方法
  • 招远网站建设公司报价推广普通话手抄报内容大全
  • 如何免费网站建设一个网站开发的流程图
  • 兰州市建设局官方网站零距离seo
  • 做移动网站多少钱建筑人才招聘网站
  • 网站建设小程序攀枝花建设工程质量监督站投诉网站
  • 丽水市莲都建设分局网站网站开发的论文引言
  • 网站建设包括哪方面网站改版
  • 网站开发算固定资产保定网站维护公司
  • 简单大气网站源码php企业公司网站源码
  • 网站被域名重定向会宁网站建设公司
  • 做美食的视频网站有哪些虚拟主机搭建网站
  • 做网站有没有效果做网站对外贸有什么用
  • 出版社网站建设旅游营销的网站建设
  • 云南网站开发网络公司微网站是自己做可以不