1.spring cloud简单入门:结合springboot

首先,引入概念分布式微服务.一般应用都是单体架构.所有的内容都是在一个项目模块,部署在一个服务器上,假如用户访问量大了,服务器压力大了怎么办?  你可以使用集群,将同样的项目COPY部署到多台服务器上,负载均衡(比如nginx).

然而,我们的应用模块的服务器压力使不一样的,比如登陆功能,邮件功能等,有些使用量大,有些使用量小,所以引出了微服务分布式概念. 我们通过将模块拆分,设置权重部署到服务器,权重大的可以多部署几台服务器,那些不怎么使用的模块用一台服务器.
spring cloud结构图
Service Discovery
A dynamic directory that enables client side load balancing and smart routing
Circuit Breaker //断路器
Microservice fault tolerance with a monitoring dashboard
Configuration Server //配置服务
Dynamic, centralized configuration management for your decentralized applications
API Gateway //网关
Single entry point for API consumers (e.g., browsers, devices, other APIs)
Distributed Tracing //分布式追踪
Automated application instrumentation and operational visibility for distributed systems
OAuth2 //支持单点登陆 token(一般使用session作为token 让用户携带上访问)
Support for single sign on, token relay and token exchange
Consumer-Driven Contracts //两种协议的支持
Service evolution patterns to support both HTTP-based and message-based APIs
View All

Spring Cloud Reference Manual
Getting Started Guides
Config
Registry
Breakers
Load Balancing
Routing

简单案例:
1.spring cloud服务注册中心Eureka
IDEA创建一个父项目 maven,删除掉src文件 因为父项目作为pom用不上
创建spring cloud 作为父项目 删除掉src文件

<?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>cn.how2j.springcloud</groupId>
    <artifactId>springcloud</artifactId>
    <version>1.0-SNAPSHOT</version>
    <description>springcloud父项目内容</description>
    <packaging>pom</packaging>
    <!--引入-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/>
    </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>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--hutool工具-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.3.1</version>
        </dependency>
    </dependencies>

    <!--统一管理项目的版本号-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

创建子项目 eureka-server,服务注册中心Eureka>>>>new model
子项目 pom.xml ,增加 spring-cloud-starter-netflix-eureka-server jar 包

<?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">
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>cn.how2j.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-server</artifactId>

    <dependencies>
        <!--eureka服务注册中心-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

</project>

EurekaServerApplication> EurekaServer 启动类。
这是一个 EurekaServer ,它扮演的角色是注册中心,用于注册各种微服务,以便于其他微服务找到和访问。 所以 Eureka 这个单词是 “找到啦” 的意思。
EurekaServer 本身就是个 Springboot 微服务, 所以它有 @SpringBootApplication 注解。
@EnableEurekaServer 表示这是个 EurekaServer 。
//可以修改为正常的springboot启动方式

package cn.how2j.springcloud;

import cn.hutool.core.util.NetUtil;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
@EnableEurekaServer //表示这是个微服务 
@SpringBootApplication
public class EurekaServerApplication {
    public static void main(String[] args) {
        //8761 这个端口是默认的,就不要修改了,后面的子项目,都会访问这个端口。
        int port = 8761;
        if (!NetUtil.isUsableLocalPort(port)) {
            System.err.printf("端口%d被占用了,无法启动%n", port);
            System.exit(1);
        }
        new SpringApplicationBuilder(EurekaServerApplication.class).properties("server.port=" + port).run(args);
    }


}

配置文件,resource下建application.yml

eureka:
  instance:
    hostname: localhost  //主机地址 比如127.0.0.1
  client:
    registerWithEureka: false   //服务中心本身也是一个微服务,这个表示不注册进来
    fetchRegistry: false 
    serviceUrl:								//地址,这是http://127.0.0.1:8761/
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

spring:
  application:
    name: eureka-server      //微服务名称

#修改服务注册中心端口,默认8761
server:
  port: 8761           //微服务的端口号
    

输入http://127.0.0.1:8761/访问注册中心 查看注册的服务等信息
结果没有微服务注册
还没有微服务注册进来,下一节注册微服务

接下来注册数据微服务:

创建子项目 product-data-service。
new module 来建一个数据微服务
创建数据微服务
pom文件添加依赖:
spring-cloud-starter-netflix-eureka-client 表示这是个 eureka 客户端。
spring-boot-starter-web: 表示这是个web服务,会提供控制层

<?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">
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>cn.how2j.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>product-data-service。</artifactId>

    <dependencies>
        <!--spring-cloud-starter-netflix-eureka-client 表示这是个 eureka 客户端。-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--spring-boot-starter-web: 表示这是个web服务,会提供控制层-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

配置pojo,server,controller层,省略部分(pojo和service)自己构造,不用数据库

package cn.how2j.springcloud.controller;

import cn.how2j.springcloud.pojo.Product;
import cn.how2j.springcloud.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
@Controller
public class ProductController {
    @Autowired
    ProductService productService;
    @ResponseBody	//返回json数据方便查看效果
    @RequestMapping("/products")
    public Object products() {
        List<Product> ps = productService.listProducts();
        return ps;
    }
}

application.yml

在模块下resources
#微服务名
spring:
  application:
    name: product-data-service  //微服务名
#和服务中心配置一致 hostname,serviceUrl:一致
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:                             //eureka服务中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
#自己的端口
server:
  port: 8001

启动类

package cn.how2j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
@SpringBootApplication
@EnableEurekaClient    //注册微服务
public class ProductDataServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductDataServiceApplication.class,args);
    }
}

启动后再次访问服务中心http://127.0.0.1:8761/ 发现注册了一个微服务:
启动发现注册了一个
访问微服务测试:http://127.0.0.1:8001//products
返回json
返回j’son

多来一份数据微服务  新建子项目maven copy一份改改
 端口不同8002,微服务名称和之前的一致 改个端口号

application.yml

#微服务名
spring:
  application:
    name: product-data-service
#和服务中心配置一致
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
#自己的端口
server:
  port: 8002

pom.xml
修改一下

<?xml version="1.0" encoding="UTF-8"?>



springcloud
cn.how2j.springcloud
1.0-SNAPSHOT

4.0.0

<artifactId>product-data-service3</artifactId>	这个修改否则子项目重名
<dependencies>
    <!--spring-cloud-starter-netflix-eureka-client 表示这是个 eureka 客户端。-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--spring-boot-starter-web: 表示这是个web服务,会提供控制层-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

启动查看:http://127.0.0.1:8761/ 一个微服务启动了两个端口.

8001,8002
**视图微服务:**接下来

Ribbon 概念
1.接下来,我们就要访问前面注册好的数据微服务了。 springcloud 提供了两种方式,一种是 Ribbon,一种是 Feign。
Ribbon 是使用 restTemplate 进行调用,并进行客户端负载均衡。 什么是客户端负载均衡呢? 在前面 注册数据微服务 里,注册了8001和8002两个微服务, Ribbon 会从注册中心获知这个信息,然后由 Ribbon 这个客户端自己决定是调用哪个,这个就叫做客户端负载均衡。

Feign 是什么呢? Feign 是对 Ribbon的封装,调用起来更简单。。。

创建视图微服务 new model…

创建子项目 product-view-service-ribbon

在这里插入图片描述
pom.xml
包含以下jar:
spring-cloud-starter-netflix-eureka-client: eureka 客户端
spring-boot-starter-web: springmvc
spring-boot-starter-thymeleaf: thymeleaf 做服务端渲染

<?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">
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>cn.how2j.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>product-view-service-ribbon</artifactId>
    <!--视图依赖包括mvc thymeleaf  eureka 客户端-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

    </dependencies>

</project>

接着创建和数据微服务一样的结构

package how2j.springcloud.pojo;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
public class Product {

    private int id;
    private String name;
    private int price;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public Product() {

    }

    public Product(int id, String name, int price) {
        super();
        this.id = id;
        this.name = name;
        this.price = price;
    }


}

Ribbon 客户端,访问数据微服务地址


Ribbon 客户端, 通过 restTemplate 访问 http://PRODUCT-DATA-SERVICE/products , 而 product-data-service 既不是域名也不是ip地址,而是 数据服务在 eureka 注册中心的名称。

注意看,这里只是指定了要访问的 微服务名称,但是并没有指定端口号到底是 8001, 还是 8002.

package how2j.springcloud.pojo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
@Component
public class ProductClientRibbon {
    //下面的对象需要自己加到容器里请看config配置
    @Autowired
    RestTemplate restTemplate;

    public List<Product> listProdcuts() {
        //数据微服务对象访问的/products
        //相当于 http://127.0.0.1:8001/products      (8001,8002其中一个)
        //返回list
        return restTemplate.getForObject("http://product-data-service/products",List.class);
    }

服务类 service
返回list对象

package how2j.springcloud.service;
import how2j.springcloud.pojo.Product;
import how2j.springcloud.pojo.ProductClientRibbon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
@Service
public class ProductService {
   @Autowired
   ProductClientRibbon productClientRibbon;

    public List<Product> listProducts(){
       // List<Product> ps = new ArrayList<>();
        //ps.add(new Product(1,"product a from port:"+port, 50));
       // ps.add(new Product(2,"product b from port:"+port, 150));
       // ps.add(new Product(3,"product c from port:"+port, 250));
       // return ps;
        return  productClientRibbon.listProdcuts();
    }
}

注意:service 业务返回的数据调用了数据微服务
(相当于中介,视图微服务先调用,再交给两个数据微服务处理,service传统是通过调用dao接口查询数据库,这里是通过Ribbon 客户端去数据微服务中调用)

控制器controller

package how2j.springcloud.controller;


import how2j.springcloud.pojo.Product;
import how2j.springcloud.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/

@Controller
public class ProductController {

    @Autowired
    ProductService productService;

    @RequestMapping("/products")
    public Object products(Model m) {
        List<Product> ps = productService.listProducts();
        m.addAttribute("ps", ps);
        return "products";
    }
}

products.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>products</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <style>
 
        table {
            border-collapse:collapse;
            width:400px;
            margin:20px auto;
        }
        td,th{
            border:1px solid gray;
        }
         
    </style>       
</head>
<body>
 
<div class="workingArea">
    <table>
        <thead>
            <tr>
                <th>id</th>
                <th>产品名称</th>
                <th>价格</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="p: ${ps}">
                <td th:text="${p.id}"></td>
                <td th:text="${p.name}"></td>
                <td th:text="${p.price}"></td>
            </tr>
        </tbody>
    </table>
</div>
 
</body>
 
</html>

启动类:

package how2j;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
@SpringBootApplication
@EnableEurekaClient			//注册到服务中心
@EnableDiscoveryClient   //启用发现其他微服务
public class ProductViewServiceRibbonApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductViewServiceRibbonApplication.class, args);
    }
}

补充:config
如何使用Ribbon
上节示例中是使用RestTemplate进行Eureka Client(包括服务提供者以及服务消费者,在这里其实是服务消费者使用RestTemplate)之间的通信,为RestTemplate配置类添加@LoadBalanced注解即可

package how2j.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
@Configuration
public class MyConfig {


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



}

yml配置:


#微服务名,以及thymeleaf设置
spring:
application:
name: product-view-service-ribbon
thymeleaf:
cache: false
prefix: classpath:/templates/
suffix: html
servlet:
content-type: text/html
encoding: utf-8
mode: html5
#和服务中心配置一致
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:8761/eureka/
#自己的端口
server:
port: 8010


全部启动测试:
1.http://127.0.0.1:8761/访问服务注册中心 eureka
在这里插入图片描述
2.查看数据微服务

http://127.0.0.1:8001//products和http://127.0.0.1:8002//products

3.访问地址:(视图微服务作为中介)

http://127.0.0.1:8010/products
报错的话建议查看微服务地址有没有写错
结果报错500,具体原因是数据微服务product-data-service 的/products请求返回的是json,而视图微服务的是返回html
所以说 controller层需要返回一致的结果
修改controller或者一一去修改每个数据微服务

@ResponseBody
@Controller
public class ProductController {

    @Autowired
    ProductService productService;

    @RequestMapping("/products")
    public Object products(Model m) {
        List<Product> ps = productService.listProducts();
        m.addAttribute("ps", ps);
        return  ps.toString();
    }
}

修改为返回json后
交给了8001端口的服务
在这里插入图片描述
8002
在这里插入图片描述
这个是轮询负载均衡机制,默认是轮着处理 我记得nginx可以设置权重 这个绝对也可以

在这里插入图片描述


Feign 方式:
概念:
Feign 是什么呢? Feign 是对 Ribbon的封装,使用注解的方式,调用起来更简单。。。 也是主流的方式~
ribbon对比:

 	public List<Product> listProdcuts() {
    return restTemplate.getForObject("http://PRODUCT-DATA-SERVICE/products",List.class);
}	

feign对比:

	@FeignClient(value = "PRODUCT-DATA-SERVICE")
public interface ProductClientFeign {
 
    @GetMapping("/products")
    public List<Product> listProdcuts();
}

好了开干吧
pom.xml添加
spring-cloud-starter-openfeign,就是用来支持 Feign 方式的。

<?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">
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>cn.how2j.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>product-view-service-feign</artifactId>
    <dependencies>
        <!--client客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--feign支持-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

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

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

    </dependencies>

</project>

pojo:

package how2j.springcloud.pojo;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
public class Product {

    private int id;
    private String name;
    private int price;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public Product() {

    }

    public Product(int id, String name, int price) {
        super();
        this.id = id;
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

Feign 客户端
Feign 客户端, 通过 注解方式 访问 访问PRODUCT-DATA-SERVICE服务的 products路径, product-data-service 既不是域名也不是ip地址,而是 数据服务在 eureka 注册中心的名称。

注意看,这里只是指定了要访问的 微服务名称,但是并没有指定端口号到底是 8001, 还是 8002.

package how2j.springcloud.client;

import how2j.springcloud.pojo.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
@Component
@FeignClient(value = "product-data-service")  //数据微服务的名称
public interface ProductClientFeign {

    @GetMapping("/products")
    public List<Product> listProdcuts(); //返回对象list

}

服务类

package how2j.springcloud.service;


import how2j.springcloud.client.ProductClientFeign;
import how2j.springcloud.pojo.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
@Service
public class ProductService {
   @Autowired
   ProductClientFeign productClientFeign;

    public List<Product> listProducts(){
       // List<Product> ps = new ArrayList<>();
        //ps.add(new Product(1,"product a from port:"+port, 50));
       // ps.add(new Product(2,"product b from port:"+port, 150));
       // ps.add(new Product(3,"product c from port:"+port, 250));
       // return ps;
        return  productClientFeign.listProdcuts();
    }
}

控制器

package how2j.springcloud.controller;


import how2j.springcloud.pojo.Product;
import how2j.springcloud.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
@ResponseBody
@Controller
public class ProductController {

    @Autowired
    ProductService productService;

    @RequestMapping("/products")
    public Object products(Model m) {
        List<Product> ps = productService.listProducts();
        m.addAttribute("ps", ps);
        return  ps.toString();
    }
}

启动类

package how2j;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @author 魏
 * @Date 2020/3/4 0004
 **/
@SpringBootApplication  //springboot启动
@EnableEurekaClient       //client注册到服务中心
@EnableDiscoveryClient   //启用发现其他微服务
@EnableFeignClients       //使用feign
public class    ProductViewServiceRibbonApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductViewServiceRibbonApplication.class, args);
    }
}

application.yml
端口修改8011

#微服务名,以及thymeleaf设置
spring:
  application:
    name: product-view-service-ribbon
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: html
    servlet:
      content-type: text/html
    encoding: utf-8
    mode: html5
#和服务中心配置一致
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
#自己的端口
server:
  port: 8011

删除掉config
测试:
在这里插入图片描述
可以看到有4个微服务 数据微服务和视图微服务 各有两个集群

访问http://localhost:8011/products 采用的-feign,不用配置config
在这里插入图片描述
待续…
发现问题了,html之前的错误是因为后缀忘记加.了 应该是
#微服务名,以及thymeleaf设置

spring:
  application:
    name: product-view-service-ribbon
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html
    servlet:
      content-type: text/html
    encoding: utf-8
    mode: html5

数据微服务 controller负责返回json数据
视图微服务 feign 接口(相当于serverImpl类)返回一个pojo对象或者list 或者 map封装的多个对象或者其他数据
视图微服务 controller 调用接口数据… 组成视图

在这里插入图片描述

链接:https://pan.baidu.com/s/13WRo6Wr-0cdIrPTs4jyffg
提取码:p016

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值