Categories
uml

uml class diagram

可用的元素声明

abstract abstract

abstract class “abstract class”

annotation annotation

circle circle

class class

diamond diamond

entity entity

enum enum

interface interface

类实体关系

Type Symbol

Extension(扩展) <|–

Composition(组合) *–

Aggregation(聚合) o–

也可以使用 extends implement

定义属性与方法

Object : equals()
ArrayList : Object[] elementData
ArrayList : size()

通过 类对象 : 方法 / 属性 定义

也可以

class

{

嵌套在类

Object[] elementData
int size()

返回属性后置

flightNumber : Integer
departureTime : Date

强制声明为field 或 method 否则根据 是否有括号判断

{field} A field
{method} Some method

}

可访问性

Character Icon for field Icon for method Visibility

-private

#protected

~ package private

+public

抽象与静态

@startuml
class Dummy {
{static} String id
{abstract} void methods()
}
@enduml

Categories
uml

plantuml

plantuml 是uml 的其中一种标准和实现形式

其代码逻辑实现由java 通过正则表达式 逐行逐行 解析uml文本

然后 生成uml的数据结构 实体的结构 关联结构 等。

具体 命令行用法

java -jar pantuml.jar XXX.puml -o XXX.png

可以把XXX.puml 转化为 png的可视化关联对象图片

以@startuml @enduml 包裹 uml代码

@startuml

开始uml

@enduml

结束uml

!inlcude $umlfile

包含/嵌套 其他uml文件

title $title

定义 uml title

title

end title

定义多行title

定义实体后 as 可以起别名

Categories
php

php artisan tinker

今天,我们将通过介绍 Laravel 中一个不太为人所知的功能,来展示如何快捷的调试数据库中的数据。通过使用 Laravel artisan 内建的 php artisan tinker, 我们可以很方便的看到数据库中的数据并且执行各种想要的操作。

Laravel artisan 的 tinker 是一个 REPL (read-eval-print-loop),REPL 是指交互式命令行界面,它可以让你输入一段代码去执行,并把执行结果直接打印到命令行界面里。

// see the count of all users
App\User::count();

// find a specific user and see their attributes
App\User::where('username', 'samuel')->first();

// find the relationships of a user
$user = App\User::with('posts')->first();
$user->posts;
factory(App\User::class, 10)->create();
App\User::all();
App\User::count();
$user = new App\User;
$user->name = "Wruce Bayne";
$user->email = "iambatman@savegotham.com";
$user->save();
doc XXX

查阅某个方法的文档

show XXX

显示某个方法的代码

Categories
php

laravel Form magic 方法

laravel 的form 对象 有magic方法 可以快速添加表单项

/**
 * Class Form.
 *
 * @method Field\Text           text($name, $label = '')
 * @method Field\Password       password($name, $label = '')
 * @method Field\Checkbox       checkbox($name, $label = '')
 * @method Field\CheckboxButton checkboxButton($name, $label = '')
 * @method Field\CheckboxCard   checkboxCard($name, $label = '')
 * @method Field\Radio          radio($name, $label = '')
 * @method Field\RadioButton    radioButton($name, $label = '')
 * @method Field\RadioCard      radioCard($name, $label = '')
 * @method Field\Select         select($name, $label = '')
 * @method Field\MultipleSelect multipleSelect($name, $label = '')
 * @method Field\Textarea       textarea($name, $label = '')
 * @method Field\Hidden         hidden($name, $label = '')
 * @method Field\Id             id($name, $label = '')
 * @method Field\Ip             ip($name, $label = '')
 * @method Field\Url            url($name, $label = '')
 * @method Field\Color          color($name, $label = '')
 * @method Field\Email          email($name, $label = '')
 * @method Field\Mobile         mobile($name, $label = '')
 * @method Field\Slider         slider($name, $label = '')
 * @method Field\File           file($name, $label = '')
 * @method Field\Image          image($name, $label = '')
 * @method Field\Date           date($name, $label = '')
 * @method Field\Datetime       datetime($name, $label = '')
 * @method Field\Time           time($name, $label = '')
 * @method Field\Year           year($column, $label = '')
 * @method Field\Month          month($column, $label = '')
 * @method Field\DateRange      dateRange($start, $end, $label = '')
 * @method Field\DateTimeRange  dateTimeRange($start, $end, $label = '')
 * @method Field\TimeRange      timeRange($start, $end, $label = '')
 * @method Field\Number         number($name, $label = '')
 * @method Field\Currency       currency($name, $label = '')
 * @method Field\SwitchField    switch($name, $label = '')
 * @method Field\Display        display($name, $label = '')
 * @method Field\Rate           rate($name, $label = '')
 * @method Field\Divider        divider($title = '')
 * @method Field\Decimal        decimal($column, $label = '')
 * @method Field\Html           html($html)
 * @method Field\Tags           tags($column, $label = '')
 * @method Field\Icon           icon($column, $label = '')
 * @method Field\Captcha        captcha($column, $label = '')
 * @method Field\Listbox        listbox($column, $label = '')
 * @method Field\Table          table($column, $label, $builder)
 * @method Field\Timezone       timezone($column, $label = '')
 * @method Field\KeyValue       keyValue($column, $label = '')
 * @method Field\ListField      list($column, $label = '')
 * @method mixed                handle(Request $request)
 */

真实调用的方法

 /**
     * Generate a Field object and add to form builder if Field exists.
     *
     * @param string $method
     * @param array  $arguments
     *
     * @return Field|$this
     */
    public function __call($method, $arguments)
    {
        if (!$this->hasField($method)) {
            return $this;
        }

        $class = BaseForm::$availableFields[$method];

        $field = new $class(Arr::get($arguments, 0), array_slice($arguments, 1));

        return tap($field, function ($field) {
            $this->pushField($field);
        });
    }
Categories
php

php __call

__call 属于php 类对象的magic 方法

当调用一个不存在与类定义的方法 就会 在call中调用

 function __call($name,$arguments) {  

 }

$name 为方法名字

$argument 为方法参数

Categories
java

DiscoverClient ribbon Feign 服务发现与调用

服务发现是 服务治理的一个很重要的点

所有注册在服务平台的微服务 必须要能被发现 然后调用

而我们调用其他服务一般有三种方法

DiscoverClient ribbon Feign

DiscoverClient 是更加低层的方法 当DiscoverClient 需要寻找服务时 其实是向服务注册器(例如 eureka) 发送 http 请求获取躯体服务信息 包括 ip port 等

@SpringBootApplication
@EnableDiscoveryClient
class Application {

    @Autowired
    DiscoveryClient discoveryClient
}

添加了注解@EnableDiscoveryClient

然后就能自动 注入 discoverClient

 @Autowired
 DiscoveryClient discoveryClient


 def restTemplate = new RestTemplate()
 def serverList = discoveryClient.getInstances("ROBIN-ADMIN")
 println(serverList)
        restTemplate.getForObject("${serverList[0].getUri()}/api/ribbon",Map.class)

获取到discoverClient 就能通过 服务名字 查找服务实例 并且通过RestTemplate 调用服务接口了

Ribbon是调用了 discoverClient 调用服务的 但是他提供了 负载均衡功能,不显式调用某个服务实例 而是通过策略调用某类服务的其中一个 达到负载均衡效果


@SpringBootApplication
class RibbonApplication {

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

在注册RestTemplate对象时 添加LoadBalanced 注解

LoadBalanced 会自动实例化restTemplate 的服务均衡策略 具体查看LoadBalance接口 会定时ping各个服务实例 也会用譬如 回环轮询策略 寻找服务实例

当restTemplate 调用服务时 通过策略调用服务实例

restTemplate.getForObject("http://ROBIN-ADMIN/api/health",Map.class)

ROBIN-ADMIN 为某类服务的服务ID

Feign 是更加接近业务的服务调用方式

maven 添加依赖

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

添加Feign注解

@EnableFeignClients
class RibbonApplication {

}

新建接口对象

package org.robin.ribbon.feign

import org.springframework.cloud.openfeign.FeignClient
import org.springframework.web.bind.annotation.RequestMapping

@FeignClient("ROBIN-ADMIN")
interface RobinAdminService {

    @RequestMapping("/api/ribbon")
    Map ribbon()


    @RequestMapping("/api/health")
    Map health()

}

spring会自动生成 RobinAdminService

调用该对象的方法 可以 调用对应微服务的接口

Categories
php

DB Facade

使用laravel 的数据库Facade 可以比较好的 执行数据库sql

$array = DB::select("select * from admin_users");
//raw 执行sql      

$object = DB::table("admin_users")->where("id","=","1")->first();
//获取查询第一条

$array = DB::table("admin_users")->where("id","=","1")->get();
//
get获取数据列表
       
$array = DB::table("admin_users")->where("id","=","1")->skip(0)->take(1)->get();
//分页查询

$array = DB::table("admin_users")->where("id","=","1")->skip(0)->limit(1)->get();
//分页查询

DB::transaction(function (){
           //内部执行开启事务
});

//手动控制事务
DB::beginTransaction();
DB::commit();
DB::rollBack();
Categories
java

eureka

作为微服务服务注册供应方

默认在本机 http://localhost:8761/eureka/提供服务

注册请求地址在 apps/{service-name} POST 发送本机服务信息

注销请求地址在 apps/{service-name}/{id} DELETE 发送请求

心跳请求地址在 apps/{service-name}/{id} PUT 发送请求

状态请求地址在 apps/{service-name}/{id}/status PUT 发送请求

删除状态请求地址在 apps/{service-name}/{id}/status DELETE 发送请求

Categories
php

php reactive socket

php socket 第三方库 composer require react/socket

该库针对 socket / 流 做事件监听(应该是epoll )主线程做事件循环 (reactive)所以该reactive 框架貌似只能在 linux下使用

server

<?php

require '../vendor/autoload.php';

echo "enter script\n";

$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server('127.0.0.1:8080', $loop);

$socket->on('connection', function (React\Socket\ConnectionInterface $connection) {
    echo "" . $connection->getRemoteAddress() . "client connected\n";
    $connection->write("Hello " . $connection->getRemoteAddress() . "!\n");
    $connection->write("Welcome to this amazing server!\n");
    $connection->write("Here's a tip: don't say anything.\n");

    $connection->on('data', function ($data) use ($connection) {
        echo "" . $data . "\n";
        //$connection->close();
    });
});

echo "server started at 8080\n";

$loop->run();

其中$loop 就是事件循环对象

client

<?php

require '../vendor/autoload.php';


$loop = React\EventLoop\Factory::create();
$connector = new React\Socket\Connector($loop);

$connector->connect('127.0.0.1:8080')->then(function (React\Socket\ConnectionInterface $connection) use ($loop) {
    echo "client connected\n";
    $connection->write("Hello World!\n");
    $connection->on('data', function ($data) use ($loop, $connection) {
        echo "" . $data . "\n";
        //$connection->close();
        //$output = new React\Stream\WritableResourceStream(fopen("./client.txt", "w"),$loop);
        //$output = fopen("./client.txt", "w");
        //fwrite($output,$data);
        //$output->write("" . $data . "\n");
        while($input = fgets(STDIN, 10))
        {
            echo $input."\n";
            $connection->write($input);

        }
    });
    /*
    $input = new React\Stream\ReadableResourceStream(STDIN,$loop);
    $input->on("data",function ($data) use ($connection) {
       $connection->write($data);
    });*/
    //$output = fopen("./client.txt", "w");
    //$steam = new React\Stream\WritableResourceStream($output,$loop);
    //$connection->pipe($steam);



});

$loop->run();

最亮眼的是 将文件描述符(标准输出流 文件输出流)fd 包装成一个响应式流对象 通过pipe实现管道功能 而且生命周期相同 会同时关闭。

Categories
php

composer 设置aliyun源

composer设置阿里云镜像源

  1. 首先把默认的源给禁用掉

composer config -g secure-http false
 

  1. 再修改镜像源 这里我使用阿里的源

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

  1. 修改成功后可以先查看一下配置

composer config -g -l
 

  1. 第二行repositories.packagist.org.url 如果是阿里的就代表成功

composer config -g -l
[repositories.packagist.org.type] composer
[repositories.packagist.org.url] https://mirrors.aliyun.com/composer/