前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于 SpringCloud 微服务架构的广告系统(第二部分:广告投放、微服务调用与断路器)

基于 SpringCloud 微服务架构的广告系统(第二部分:广告投放、微服务调用与断路器)

作者头像
营琪
发布2019-11-13 14:33:27
8320
发布2019-11-13 14:33:27
举报
文章被收录于专栏:营琪的小记录营琪的小记录

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

代码语言:txt
复制
                 本文链接:[https://blog.csdn.net/weixin\_43126117/article/details/102918751](https://blog.csdn.net/weixin_43126117/article/details/102918751) 

目录

广告系统架构图

四、sponsor模块(广告投放)

sponsor模块(广告投放)介绍图

数据库对应的实体类 (例子)

Dao接口实现 (例子)

service实现(例子)

controller 控制层(例子)

sponsor(广告投放)示意图(单个-例子)

五、Feign与Ribbon微服务相互访问(RPC)与hystrix断路器使用

Ribbon+Hystrix方式

Feign方式


第一部分:eureka、zuul、通用模块(不讲代码实现,下载代码自己看。)

这不是一个完整的广告系统,主要涉及两方面 广告检索 、广告投放 ,这两个方面我感觉是最重要的,但是也使用Kafka的消息传递,为剩下的曝光见监测、 报表 、扣费 这三个部分留下了接口。

第二部分:主要会介绍广告投放、hystrix断路器。打算随便介绍一下,也就是MVC架构设计模式,Model层数据的操作,数据库实体类对象等;Controller层控制层对外提供服务(跳转),对内访问Model层;没有用户ui等,都是后端接口,所以,也就没有view层了。

广告系统架构图

简略的广告系统架构图

所使用到的技术

JDK 、Kafka 、MySQL

框架 SpringCloud: Finchley.RELEASE 、Spring 、Spring Data JPA 、Spring boot

源码 : github https://github.com/yingyingqiqi/luoweiying-ad-spring-cloud/tree/master

四、sponsor模块(广告投放)

sponsor模块(广告投放)介绍图

maven坐标(简化版)

代码语言:javascript
复制
artifactId>spring-boot-starter-web</artifactId>            //web功能
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>    //euraka客户端
<artifactId>spring-boot-starter-data-jpa</artifactId>      //jpa规范+hibernate+spring jdbc
<artifactId>mysql-connector-java</artifactId>            //驱动
<artifactId>commons-codec</artifactId>                    //apache工具类

这里介绍一下spring data jpa: 很久以前,数据库的持久层有一套标准--ORM(对象关系映射,就是把数据库映射成对象),一些第三方公司根据这个标准,做了一些ORM框架,如:hibernate、TopLink等,sun整合了第三方框架,推出一套JPA规范,spring data jpa是在这个jpa规范+hibernate+jdbc再次的封装,越封装、越难理解底层代码,但是对于广告投放这个项目,对数据库的性能要求不高,后面会介绍。

一些介绍可以看这里 spring data jpa 详解 SpringData JPA 官方文档

配置(不用看)

代码语言:javascript
复制
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8000/eureka
server:
  port: 7000
  servlet:
    path: /ad-sponsor
spring:
  application:
    name: eureka-client-ad-sponsor
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: none
    properties:
      hibernate.format_sql: true
    open-in-view: false
  datasource:
    url: jdbc:mysql://ip:3306/ad_data?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=false
    username: 
    password: 
    tomcat:
      max-active: 40
      min-idle: 20
      initial-size: 4

数据库对应的实体类 (例子)

代码语言:javascript
复制
package cn.luoweiying.entity;
@Entity                    //标记为实体类
@Table(name = "ad_plan")    //与数据库对应的表名
public class AdPlan {

    @Id          //主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)    //主键序号方式
    @Column(name = "id", nullable = false)                 //对应列名
    private Long id;

    @Column(name = "user_id", nullable = false)            //对应列名
    private Long userId;

详细的hibernate注解 可以看官方文档, 也可以看 JPA注解详解

Dao接口实现 (例子)

代码语言:javascript
复制
public interface AdPlanRepository extends JpaRepository<AdPlan, Long> {

    AdPlan findByIdAndUserId(Long id, Long userId);       //跟spl类似,不用写sql语句

    List<AdPlan> findAllByIdInAndUserId(List<Long> ids, Long userId);

接口继承Repository<T, ID> ,就可以在自己的dao接口定义方法,只用写关键字,不用写sql语句,每个关键字有特定意思,不用写dao接口的实现,自动实现了。

继承JpaRepository类并添加泛型,会自动实现一些方法,此步骤也可以作为如何定义方法的回想线索。

spring支持的自定义关键字查询 ,可以查看 Appendix C: Repository query keywords SpringDataJPA自定义关键字查询

vo对象, 方法间传递的对象(例子)

代码语言:javascript
复制
public class AdPlanRequest {

    private Long id;
    private Long userId;
    private String planName;
    private String startDate;
    private String endDate;

    public boolean createValidate() {            //检查方法是否为空
        return userId != null && !StringUtils.isEmpty(planName)
  && !StringUtils.isEmpty(startDate)&& !StringUtils.isEmpty(endDate);
    }
代码语言:javascript
复制
public class AdPlanResponse {

    private Long id;
    private String planName;
}

这些vo对象,方法间相互调用,传递的对象,相当于一个数据结构,dao--service--controller调用更加清晰明了。

service接口定义(例子)

代码语言:javascript
复制
public interface IAdplanService {
  
    AdPlanResponse createAdPlan(AdPlanRequest request) throws AdException;//创建推广计划

    List<AdPlan> getAdPlanByIds(AdPlanGetRequest request) throws AdException;//获取推广单元

service实现(例子)

代码语言:javascript
复制
@Service
public class AdPlanServiceImpl implements IAdplanService {
    @Autowired
    AdPlanRepository adPlanRepository;
   @Transactional
    public AdPlanResponse createAdPlan(AdPlanRequest request) throws AdException {
        if (!request.createValidate())throw new AdException(CodeMsg.REQUEST_PARAM_ERROR);
        
        Optional<AdUser> adUser = adUserRepository.findById(request.getUserId());
        if (!adUser.isPresent()) throw new AdException(CodeMsg.CAN_NOT_FIND_RECORD);//确保关联的User不存在

        AdPlan oldPlan = adPlanRepository.findByUserIdAndPlanName(request.getUserId(), request.getPlanName());
        if (oldPlan != null)  throw new AdException(CodeMsg.SAME_NAME_UNIT_ERROR);//同名推广计划

        AdPlan newPlan = adPlanRepository.save(new AdPlan(request.getUserId(), request.getPlanName(),
    CommonUtils.parseStringDate(request.getStartDate()),CommonUtils.parseStringDate(request.getEndDate())
        ));
        return new AdPlanResponse(newPlan.getId(),newPlan.getPlanName());

controller 控制层(例子)

代码语言:javascript
复制
@Slf4j
@RestController             //==responsebody+controller
public class AdPlanOPController {
    @Autowired
    AdPlanServiceImpl adPlanService;
    @PostMapping("/create/adPlan")
    public AdPlanResponse createAdPlan(@RequestBody AdPlanRequest request) throws AdException {
        log.info("ad-sponsor:creatAdPlan: -> {}", JSON.toJSON(request));
        return adPlanService.createAdPlan(request);
    }

sponsor(广告投放)示意图(单个-例子)

这只是单个访问的接口的例子,全部的太多了,下载源码自己看吧。

五、Feign与Ribbon微服务相互访问(RPC)与hystrix断路器使用

hystrix短路器介绍

这个项目没真正使用到微服务相互访问,并不需要调用,检索系统提供给媒体方,但是这个模块没有写,也就不需要调用了。

这里简单讲一下微服务相互访问的方式。

微服务相互访问,通讯的协议应该是"http",目前有两种常用的调用:

1.ribbon+spring restTemplate

2.feign(ribbon+hystrix) 声明式接口的形式

这两种也就是对 apache httpClient 的封装,方便微服务的使用吧。

Ribbon+Hystrix方式

坐标(简化)

代码语言:javascript
复制
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
artifactId>spring-cloud-starter-netflix-hystrix</artifactId>//断路器

配置eureka

(第一部分有)

注入 RestTemplate

代码语言:javascript
复制
@EnableEurekaClient //@EnableDiscoveryClient其他服务注册中心
@EnableHystrix  //内部有@EnableCircuitBreaker
@SpringBootApplication
public class SearchApplication {
    public static void main(String[] args) {SpringApplication.run(SearchApplication.class, args);}
    //基于Ribbon实现微服务调用
    @Bean
    @LoadBalanced  //开启默认Ribbon
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

服务调用

代码语言:javascript
复制
@HystrixCommand(fallbackMethod = "这里有断路器-例子")   //使用断路器
@PostMapping("/getAdPlansByRibbon")            //Spring MVC 的controller
public CommonResponse<List<AdPlan>> getAdPlansByRibbon(@RequestBody AdPlanGetRequest request) {
    return restTemplate.postForEntity("http://eureka-client-ad-sponsor/ad-sponsor/get/adPlan",
        request, CommonResponse.class).getBody();}

Feign方式

坐标(简版) feign引入ribbon+hystrix等

代码语言:javascript
复制
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>

配置eureka

(第一部分有)

启动类加上@EnableFeignClients

实现服务调用

代码语言:javascript
复制
@FeignClient(value = "eureka-client-ad-sponsor",fallback = SponsorClientHystrix.class)
public interface SponsorClient {
    @RequestMapping(value = "/ad-sponsor/get/adPlan",method = RequestMethod.POST)
    List<AdPlan> getAdPlans(@RequestBody AdPlanGetRequest request) throws AdException;
}

声明式的接口,外部直接调用方法就可以了,这个加了一个断路器SponsorClientHystrix

代码语言:javascript
复制
@Component
public class SponsorClientHystrix implements SponsorClient {
    @Override
    public List<AdPlan> getAdPlans(AdPlanGetRequest request) throws AdException {
        throw new AdException(CodeMsg.EUREKA_CLIENT_AD_SPONSOR_ERROR);}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-11-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 广告系统架构图
  • 四、sponsor模块(广告投放)
    • sponsor模块(广告投放)介绍图
      • 数据库对应的实体类 (例子)
        • Dao接口实现 (例子)
          • service实现(例子)
            • controller 控制层(例子)
              • sponsor(广告投放)示意图(单个-例子)
              • 五、Feign与Ribbon微服务相互访问(RPC)与hystrix断路器使用
                • Ribbon+Hystrix方式
                  • Feign方式
                  相关产品与服务
                  数据库
                  云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档