在具有中央ElastiCache(redis)集群的多个AWS EC2实例上运行分布式SF3.3应用程序.
每个EC2实例还运行一个本地Redis实例,该实例用于Doctrine元和查询缓存.
该应用程序使用Doctrines二级缓存,从功能的角度来看,它非常有效.但是AWS上的性能很差(900-1200ms页面加载),因为它在我们的许多页面上所需的Country和VatRate实体中加载了400多个缓存调用.
由于这些Country和VatRate实体很少更改,我想通过使用二级缓存中定义的不同区域来利用本地Redis实例和ElastiCache进行结果缓存.这应该可以减少400+缓存调用的延迟问题,因为在单个框页面上运行时,加载次数为100毫秒.阅读文档这一切似乎都是可能的,只是不完全确定如何使用Symfony和PHP-Cache进行配置.
应用程序/配置/ config.yml
doctrine:
dbal:
# .. params
orm:
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
default:
auto_mapping: true
second_level_cache:
enabled: true
region_cache_driver:
type: service
id: doctrine.orm.default_result_cache
cache_adapter:
providers:
meta: # Used for version specific
factory: 'cache.factory.redis'
options:
host: 'localhost'
port: '%redis_local.port%'
pool_namespace: "meta_%hash%"
result: # Used for result data
factory: 'cache.factory.redis'
options:
host: '%redis_result.host%'
port: '%redis_result.port%'
pool_namespace: result
cache:
doctrine:
enabled: true
use_tagging: true
metadata:
service_id: 'cache.provider.meta'
entity_managers: [ default ]
query:
service_id: 'cache.provider.meta'
entity_managers: [ default ] …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建我们订单的汇总报告,但无法在单个查询中提取所有需要的数据。
我想提取的数据:
订单表(针对本示例进行了简化)
| orderId | deliveryTotal | total |
|---------|---------------|-------|
| 1 | 5 | 15 |
| 2 | 5 | 15 |
| 3 | 7.50 | 27.50 |
Run Code Online (Sandbox Code Playgroud)
订购项目表
| orderItemId | orderId | productId | salePrice | quantity |
|-------------|---------|-----------|-----------|----------|
| 1 | 1 | 1 | 10 | 1 |
| 2 | 2 | 1 | 10 | …Run Code Online (Sandbox Code Playgroud) 我目前有一个相当复杂的本机SQL查询,用于报告目的.鉴于它处理的数据量,处理它的唯一有效方法是使用本机SQL.
这很好,并从标量结果返回一个数组数组.
我想做的是,为了使结果与项目中的每个其他结果集一致,使用数据传输对象(DTO).返回一组简单的DTO对象.
这些在DQL中工作得很好,但我无法看到它们与原生SQL一起使用它们.这是可能吗?
我可能会以完全错误的方式进行操作,但是我有一个onKernelRequest事件设置,该事件设置获取当前域(单个应用程序上的多个站点),查询缓存/数据库并将其存储在服务中,以供其他控制器/服务使用。这很完美。
现在,如果找不到域,我想抛出404错误。通常,我只是在控制器中执行以下操作:
throw new NotFoundHttpException('Not found!');
Run Code Online (Sandbox Code Playgroud)
但这会导致生产中出现未捕获的异常,因此我假设由于事件的优先级(31)。
PHP Fatal error: Uncaught exception 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException' with message 'Not found!'
Run Code Online (Sandbox Code Playgroud)
我当前的代码(为清楚起见,删除了逻辑),请注意,我使用JMSDiExtraBundle配置服务。
/**
* @Service
*/
class CurrentDomainListener
{
/**
* @Observe("kernel.request", priority=31)
*/
public function onKernelRequest(GetResponseEvent $event)
{
// find domain in cache/database...
if (!$domain) {
throw new NotFoundHttpException('Not found!');
}
// store domain in service...
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,当域不存在时显示404错误的最佳方法是什么?
我对此做了一些研究,感觉好像我已经完成了 80% 的工作,但由于分割其中一根字符串,我很难根据需要调整 jq 输出。
我正在尝试将 AWS SSM 的 JSON 输出转换为环境变量。
AWS命令
aws ssm get-parameters-by-path \
--path /qa/es \
--with-decryption \
--query 'Parameters[*].{Name:Name,Value:Value}' \
Run Code Online (Sandbox Code Playgroud)
输出
[
{
"Name": "/qa/es/AWS_ACCESS_KEY_ID",
"Value": "ABC123"
},
{
"Name": "/qa/es/AWS_SECRET_ACCESS_KEY",
"Value": "abcdefghijkl"
},
{
"Name": "/qa/es/ENDPOINT",
"Value": "https://amazonaws.com"
}
]
Run Code Online (Sandbox Code Playgroud)
我所需的 jq 输出,请注意,我仅在最后一个 / 之后的环境变量之后。在某些情况下,这可能是 /qa/es/something/nested/ENV_VAR
AWS_ACCESS_KEY_ID=ABC123
AWS_SECRET_ACCESS_KEY=abcdefghijkl
ENDPOINT=https://amazonaws.com
Run Code Online (Sandbox Code Playgroud)
一旦我有了这个,我就可以利用这里的答案来设置环境变量。将 JSON 导出到环境变量
我最接近的是
jq -r "map(\"\(try(.Name |= split(\"/\")))=\(.Value|tostring)\")|.[]" params.json
Run Code Online (Sandbox Code Playgroud)
这给了我
{"Name":["","qa","es","AWS_ACCESS_KEY_ID"],"Value":"ABC123"}=ABC123
{"Name":["","qa","es","AWS_SECRET_ACCESS_KEY"],"Value":"abcdefghijkl"}=abcdefghijkl
{"Name":["","qa","es","ENDPOINT"],"Value":"https://amazonaws.com"}=https://amazonaws.com
Run Code Online (Sandbox Code Playgroud)
接近,但还不够接近!有人能在这里指出正确的方向吗?
我大量使用实体监听器进行日志记录,通常工作得很好并且将所有代码保留在控制器/服务之外.
我无法实现的一件事是记录添加到ManyToMany关系的项目.在这种情况下,我想记录从产品中添加/删除大小的时间
/**
* @ORM\Entity
* @ORM\EntityListeners({"EventListener\ProductListener"})
* @ORM\Table(name="products")
*/
class Product
{
// ...
/**
* @var ArrayCollection
*
* @ORM\ManyToMany(targetEntity="Size")
* @ORM\JoinTable(name="productSizes",
* joinColumns={@ORM\JoinColumn(name="productId", referencedColumnName="productId")},
* inverseJoinColumns={@ORM\JoinColumn(name="sizeId", referencedColumnName="sizeId")}
* )
*/
protected $sizes;
/**
* @param Size $size
* @return Product
*/
public function addSize(Size $size)
{
$this->sizes[] = $size;
return $this;
}
/**
* @param Size $size
*/
public function removeSize(Size $size)
{
$this->sizes->removeElement($size);
}
/**
* @return ArrayCollection
*/
public function getSizes()
{
return $this->sizes;
} …Run Code Online (Sandbox Code Playgroud)