Spring cloud实战 从零开始一个简单搜索网站(三)

上文已经完成了一个简单的   浏览器 到 Client 到CSDN端的通路

我们的架构是每个博客网址为一个单独的组件, 这里为了方便直接先用CSDN 那个组件复制下

我这里改成 SDN 修改下 application.properties   端口记得改

eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.application.name=sdn
server.port=8983

下面是TOMCAT   和 eureka server运行的截图

好了 有两个搜索端了,我这里把CSDN  SDN 叫做搜索端了 , 下面修改下 Client端  让他能分别调用2个组件


我修改了下github上的配置  把我们新建的serviceID加入进去

我们会回到Client项目的  ClientService 多了个SDN,需要修改下代码,能让程序自动加载多个HOST(这里只是简单介绍,如果搜索端好几个肯定得改进)

@Service
public class ClientService {
    @Autowired RestTemplate restTemplate;
    @Autowired
    private EurekaClient discoveryClient;

    @Value("${serviceIds}")
    public String serviceIds;

    public String  search(String key,String page) {
        StringBuffer sb =new StringBuffer();
        if(serviceIds.contains(",")) {
            String[] ids = serviceIds.split(",");
            for(int i=0;i<ids.length;i++) {
                sb.append(searchDetail(key, page, ids[i]));
            }
        }
        else {
            sb.append(searchDetail(key, page,serviceIds));
        }
        return sb.toString();
    }

    public String  searchDetail(String key,String page,String serviceId) {
        HashMap<String, String> map = new HashMap<>();
        map.put("key", key);
        map.put("page", page);
        String str= restTemplate.getForObject(serviceUrl(serviceId)+"/search?key={key}&page={page}",String.class,map);
        return str;
    }
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
    public String serviceUrl(String serviceId) {
        InstanceInfo instance = discoveryClient.getNextServerFromEureka(serviceId, false);
        return instance.getHomePageUrl();
    }
}

因为数据比较多  我把两个搜索端直接改成返回一个字符串了

@RestController
public class CsdnController {
    Gson gson = new Gson();

    @RequestMapping(value = "/search")
    public String search(@RequestParam("key") String key, @RequestParam("page") String page) {
        System.out.println("search");
        ArrayList<HashMap<String, String>> result;
        try {
//            result = SearchUtil.search(key, "blog", page);
//            return gson.toJson(result);
            return "i am csdn 1";
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

public class CsdnController {
    Gson gson = new Gson();

    @RequestMapping(value = "/search")
    public String search(@RequestParam("key") String key, @RequestParam("page") String page) {
        System.out.println("search");
        ArrayList<HashMap<String, String>> result;
        try {
//            result = SearchUtil.search(key, "blog", page);
//            return gson.toJson(result);
            return "i am sdn 1";
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

这下有两个端了,搜索时间也延长了2倍, 但万一个端有异常  另外一个端良好 怎么办 这时候就需要断路由 hystrix

在client pom里面导入下

            <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>

POM 代码

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>tsearch_web</groupId>
    <artifactId>springtest-client</artifactId>
    <version>0.0.1</version>
    <packaging>jar</packaging>

    <name>springtest-client</name>
    <description>Note Server catch</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.M3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

            <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.RELEASE</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>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>

修改下application

@EnableEurekaClient
@SpringBootApplication
@EnableCircuitBreaker
public class SpringtestClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringtestClientApplication.class, args);
    }
}

新增个SearchUtil 类

@Component
public class SearchUtil  {
    @Autowired
    RestTemplate restTemplate;
    @Autowired
    private EurekaClient discoveryClient;

    @HystrixCommand(groupKey = "searchDetail1", commandKey = "searchDetail1",fallbackMethod = "stubMyService")
    public String searchDetail1(String key, String page, String serviceId) {
        System.out.println("come="+serviceId);
        HashMap<String, String> map = new HashMap<>();
        map.put("key", key);
        map.put("page", page);
        String str = restTemplate.getForObject(serviceUrl(serviceId) + "/search?key={key}&page={page}", String.class,
                map);
        return str;
    }

    @HystrixCommand(groupKey = "searchDetail2", commandKey = "searchDetail2",fallbackMethod = "stubMyService")
    public String searchDetail2(String key, String page, String serviceId) {
        System.out.println("come="+serviceId);
        HashMap<String, String> map = new HashMap<>();
        map.put("key", key);
        map.put("page", page);
        String str = restTemplate.getForObject(serviceUrl(serviceId) + "/search?key={key}&page={page}", String.class,
                map);
        return str;
    }

    public String stubMyService(String key, String page, String serviceId) {
        return "error";
    }

    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public String serviceUrl(String serviceId) {
        InstanceInfo instance = discoveryClient.getNextServerFromEureka(serviceId, false);
        return instance.getHomePageUrl();
    }
}

修改下 ClientService

@Service
public class ClientService {
    @Autowired
    SearchUtil sc;

    @Value("${serviceIds}")
    public String serviceIds;

    public String search(String key, String page) {
        StringBuffer sb = new StringBuffer();
        if (serviceIds.contains(",")) {
            String[] ids = serviceIds.split(",");
            sb.append(sc.searchDetail1(key, page, ids[0]));
            sb.append(sc.searchDetail2(key, page, ids[1]));
        }
        else {
            sb.append(sc.searchDetail1(key, page, serviceIds));
        }
        return sb.toString();
    }

}

不断刷新 浏览器 好像没啥区别

给CSDN的Client加个超载

@RestController
public class CsdnController {
    Gson gson = new Gson();

    @RequestMapping(value = "/search")
    public String search(@RequestParam("key") String key, @RequestParam("page") String page) {
        System.out.println("search");
        ArrayList<HashMap<String, String>> result;
        try {
//            result = SearchUtil.search(key, "blog", page);
//            return gson.toJson(result);
            Thread.sleep(5000);
            return "i am csdn 1";
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

继续刷新

然后看下控制台   不是说好的垄断吗  为啥 还是进来了 虽然时间减少了

用Hystrix的时候要注意一点  Hystrix的 超时时间一点要大于resttemplete  或者你用 ribbon

Hystrix 的默认值全在  com.netflix.hystrix.HystrixCommandProperties

这个就是出错次数 private static final Integer default_circuitBreakerRequestVolumeThreshold = 20;// default => statisticalWindowVolumeThreshold: 20 requests in 10 seconds must occur before statistics matter

我们改下 SearchUtil

@Component
public class SearchUtil  {
    @Autowired
    RestTemplate restTemplate;
    @Autowired
    private EurekaClient discoveryClient;

    @HystrixCommand(groupKey = "searchDetail1", commandKey = "searchDetail1",fallbackMethod = "stubMyService",
            commandProperties = {
                     @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "5")
                })
    public String searchDetail1(String key, String page, String serviceId) {
        System.out.println("come="+serviceId);
        HashMap<String, String> map = new HashMap<>();
        map.put("key", key);
        map.put("page", page);
        String str = restTemplate.getForObject(serviceUrl(serviceId) + "/search?key={key}&page={page}", String.class,
                map);
        return str;
    }

    @HystrixCommand(groupKey = "searchDetail2", commandKey = "searchDetail2",fallbackMethod = "stubMyService")
    public String searchDetail2(String key, String page, String serviceId) {
        System.out.println("come="+serviceId);
        HashMap<String, String> map = new HashMap<>();
        map.put("key", key);
        map.put("page", page);
        String str = restTemplate.getForObject(serviceUrl(serviceId) + "/search?key={key}&page={page}", String.class,
                map);
        return str;
    }

    public String stubMyService(String key, String page, String serviceId) {
        return "error";
    }

    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public String serviceUrl(String serviceId) {
        InstanceInfo instance = discoveryClient.getNextServerFromEureka(serviceId, false);
        return instance.getHomePageUrl();
    }
}

重启下 不断刷新浏览器    发现 searchDetail1方法不执行了  好了  垄断完成

我们需要知道组件的当前状态  这时候就需要hystrix的dashbox

POM 中引入

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>

修改下ClientApplication 加入dashboard注释

@EnableEurekaClient
@SpringBootApplication
@EnableCircuitBreaker
@EnableHystrixDashboard
public class SpringtestClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringtestClientApplication.class, args);
    }
    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

在浏览器输入http://localhost:8881/hystrix 就能看到界面

按上面的填写好  点击Monitor Stream就能进入统计页面

写个函数拼命跑 会发现数字多有变化 鼠标放上去可以看到具体说明

public class TestHystic {
    public static void main(String[]  args) {
        long time1=System.currentTimeMillis();
        String b ="";
        System.out.println(b.length());
        for(int i=0;i<100;i++) {
            try {
                getData();
                System.out.println("usertime="+(System.currentTimeMillis()-time1));
                time1=System.currentTimeMillis();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public static  void  getData() throws Exception {
        URL serverUrl = new URL("http://localhost:8881/search?key=spring&page=1");
        HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection();
        InputStream in = conn.getInputStream();
        BufferedReader br =new BufferedReader(new InputStreamReader(in, "UTF-8"));
       StringBuffer sb= new StringBuffer();
       String line;
        while((line=br.readLine())!=null) {
            sb.append(line);
        }
        System.out.println(sb.toString());
        in.close();
    }
}

原文地址:https://www.cnblogs.com/dikeboy/p/10060569.html

时间: 2024-07-30 09:25:26

Spring cloud实战 从零开始一个简单搜索网站(三)的相关文章

Spring cloud实战 从零开始一个简单搜索网站(一)

效果地址http://121.40.36.198:9080/web/ 本文从建站开始,就不跟别的顺序一样要怎么开始开始的,懂java就行 我会尽量讲的详细, 首先肯定是工具的选择 ,俗话说工欲善其事,必先利其器,Eclipse 和IDEA 都可以集成Spring 插件,不过最好还是用Spring Tool suite ,它有三个版本,看个人喜好,我比较偏向eclipse 安装完后 第一步 记得把maven 改成阿里云的 软件安装完后New - Spring start Project  然后填写

Spring cloud实战 从零开始一个简单搜索网站(四)

上篇用了2个方法来来做断路由,太蛋疼了  Spring Cloud集成的是javanica hystrix 虽然集成方便了很多,不过 javanica默认好像不支持 动态修改 commandKey , Hystrix是根据commandKey来分配每个熔断器的  网上也有些解决办法 不过感觉还是太蛋疼了  算了 还是直接用Hystrix好了 先把javanica hystrix的引用换成 hystrix core <dependency> <groupId>com.netflix.

Spring Cloud实战之初级入门(四)— 利用Hystrix实现服务熔断与服务监控

目录 1.环境介绍 2.服务监控 2.1 加入依赖 2.2 修改配置文件 2.3 修改启动文件 2.4 监控服务 2.5 小结 3. 利用hystrix实现消费服务熔断 3.1 加入服务熔断 3.2 测试服务熔断 4. 利用turbine监控所有应用 4.1 创建工程 4.2 修改配置文件 4.3 修改启动文件 4.4 启动 5.一点点重要的事情 1.环境介绍 本篇文章涉及到前面文章的工程,mirco-service-provider.mirco-service-consumer以及需要另外新建

《重新定义Spring Cloud实战(许进 等著)》 高清pdf

<重新定义Spring Cloud实战> Spring Cloud中国社区出品,核心成员来自原阿里.蚂蚁金服和*金融等,BAT近10位专家力荐,内容足够广.有深度.重生产实践 ? 百度网盘链接: https://pan.baidu.com/s/1iAWBPi2J_ATTYsjzl41dnw 提取码: yhjx 内容简介 这是一本实践与理论并重.广度与深度兼顾的Spring Cloud生产实践开发指南,由SpringCloud中国社区倾力打造,作者来自阿里.蚂蚁金服.*金融等企业,本书针对Spr

spring cloud实战 1-高可用注册中心

创建父maven项目 提交代码至GitHub 创建eureka-server-1 项目搭建两种方式: 父pom中继承spring-boot-starter-parent,子pom中直接结成父pom.该方式比较方便,但子项目都是spring boot项目了. 父项目不需要继承spring-boot-starter-parent,子pom中通过使用scope = import依赖关系. 123456789101112 <dependencyManagement> <dependencies&

一个简单的网站访问过程

对于我们一个简单的网站访问,涉及到的技术: 1.用户访问浏览器时,浏览器会向服务器发出一个 HTTP 请求: 2.服务器接收到 HTTP 请求,Web Server 进行相应的初步处理,使用服务器脚本生成页面: 3.服务器脚本(利用Web Framework)调用本地和客户端传来的数据,生成页面: 4.Web Server 将生成的页面作为 HTTP 响应的 body,根据不同的处理结果生成 HTTP header,发回给客户端: 5.客户端(浏览器)接收到 HTTP 响应,通常第一个请求得到的

学生成绩管理后台第二项任务:初步建模,搭建一个简单的网站

负责人:程琳茹 合伙人:李玉婷 签约员工:闫玉荣 前言:学生成绩管理后台,看起来是一个简单的项目,但是对于我们今后的发展很重要,建设一个管理后台有很多方法,这里我们主要使用Rstudio,在之后的文章中,会详细给出我们小组完成项目的过程与遇到的问题,欢迎大家借鉴,此外,同学们要积极参与讨论. 项目步骤:1.熟悉与安装Rstudio,并且配置好R内部环境. 2.建立好文件所存放的位置与确保文档可以正常使用. 3.搭建一个简单的网站,分别分为server.R端口与ui.R端口. 4.搭建好网站后,插

3.开始使用Spring Cloud实战微服务

                 开始使用Spring Cloud实战微服务 3.1. Spring Cloud实战前提 3.1.1. 需要的技术储备 3.1.2. 使用的工具及软件版本 3.2. 服务提供者与服务消费者 3.3. 编写服务提供者 3.3.1. 手动编写项目 3.3.2. 使用Spring Initializr快速创建Spring Boot项目 3.4. 编写服务消费者 3.5. 为项目整合Spring Boot Actuator 3.6. 硬编码有哪些问题 原文地址:https

【spring cloud】导入一个新的spring boot项目作为spring cloud的一个子模块微服务,怎么做/或者 每次导入一个新的spring boot项目,IDEA不识别子module,启动类无法启动/右下角没有蓝色图标

如题:导入一个新的spring boot项目作为spring cloud的一个子模块微服务,怎么做 或者说每次导入一个新的spring boot项目,IDEA不识别,启动类无法启动,怎么解决 下面一起来走一遍这个流程: 1.将一个spring boot服务导入spring cloud中作为一个子模块 如图:这里有一个现成的spring cloud微服务集群,[如何创建一个spring cloud微服务:https://www.cnblogs.com/sxdcgaq8080/p/9035724.h